Merging transmission pair data gets rid of all of W17 ferrets - avoid this

library("tidyr")
library('ggplot2')
library('dplyr')
library("ggVennDiagram")
library("glue")

wkdir = "~/Desktop/GitHub/Obesity/NewExtractions/H9N2"
setwd(wkdir)
savedir = "~/Desktop/GitHub/Obesity/NewExtractions/H9N2/Output_Figures"

source("~/Desktop/GitHub/Obesity/NewExtractions/H9N2/FD_functions.R")
diet = c("Obese","Lean","Control")
dietColors = c("#FF9933","#66CCFF","#606060")
names(dietColors) = diet
DietcolScale_fill <- scale_fill_manual(name = "grp",values = dietColors)
DietcolScale <- scale_colour_manual(name = "grp",values = dietColors)

#Loading metadata This includes titer and Ct values when applicable. ND indicates qPCR was run with a negative result; 0 indicates plaque assay or HAI was run with a negative result. NA for any values indicate that data was missing. Sacrificed indicates there was no data at that time point because the ferret had already been sacrficied for pathology.

metafile = "H9_Metadata.csv"

meta = read.csv(file=metafile,header=T,sep=",",na.strings = c(''))
meta = filter(meta, resequenced == "yes")

meta$Ct_Mgene = as.numeric(meta$Ct_Mgene)
Warning: NAs introduced by coercion
meta$titer = as.numeric(meta$titer)
Warning: NAs introduced by coercion
meta$log10_titer = as.numeric(meta$log10_titer)
Warning: NAs introduced by coercion
meta$inf_route = factor(meta$inf_route, levels = c("Index","Contact","Aerosol","Control"))

Pre Sequence Analysis

Ct & Titer Analysis

meta$inf_route = factor(meta$inf_route, levels = c("Index","Contact","Aerosol","Control"))

CT_plot = ggplot(filter(meta, inf_route == "Index" | inf_route == "Contact"), 
       aes(x = DPI, y = Ct_Mgene, color = as.character(ferretID))) +
  geom_point(size = 3) +
  geom_line(aes(group = ferretID), size = 1.5) +
  geom_hline(yintercept = 30, linetype = "dotted") +
  facet_grid(diet~inf_route) +
  PlotTheme1
print(CT_plot)
ggsave("CT_plot.png",CT_plot, path = savedir, width = 15, height = 7)


Titers_plot = ggplot(filter(meta, inf_route == "Index" | inf_route == "Contact"), 
       aes(x = DPI, y = log10_titer, color = as.character(ferretID))) +
  geom_point(size = 3) +
  geom_line(aes(group = ferretID), size = 1.5) +
  ylim(0,7) +
  facet_grid(diet~inf_route) +
  PlotTheme1
print(Titers_plot)
ggsave("Titers_plot.png",Titers_plot, path = savedir, width = 15, height = 7)

Sequencing Analysis

Specifying thresholds and plotting variables

cov_cut = 200
freq_cut = 0.01
pvalcut  = 0.05

ntlist = c("A","C","G","T")
SEGMENTS = c('H9N2_PB2','H9N2_PB1','H9N2_PA','H9N2_HA','H9N2_NP','H9N2_NA','H9N2_MP','H9N2_NS')

Loading in coverage file & segment size information

cov = read.csv("./avg_coverage/H9N2.coverage.csv", header = TRUE, sep = ",")

seg_sizes = "SegmentSize.csv"
sizes = read.csv(file=seg_sizes,header=T,sep=",",na.strings = c(''))
GenomeSize = (sizes %>% filter(segment == 'H9N2_GENOME'))$SegmentSize

cov$segment = factor(cov$segment, levels = SEGMENTS)

Checking if data passes thresholds & make coverage plots

cov_check = CoverageAcross(cov,cov_cut,70,sizes, wkdir)
Coverage cutoff is: 200x
Percentage covered cutoff is: 70%
cov_qual = select(cov_check, name, quality)
cov_avgtiter = merge(cov, cov_qual, by = c("name"))

cov_avgtiter$totalcount[is.na(cov_avgtiter$totalcount)] = 0
cov_avgt = group_by(cov_avgtiter,segment,ntpos,quality) %>%
  mutate(avg_cov = mean(totalcount))

avg_titer_plot = ggplot(cov_avgt, aes(x = ntpos, y = avg_cov, color = quality)) +
  geom_line() +
  facet_grid(~segment) +
  PlotTheme1
print(avg_titer_plot)
ggsave("avg_titer_plot.pdf",avg_titer_plot,path = savedir, width = 10, height = 5)

Merging coverage check info with the rest of the metadata

meta = merge(meta, cov_check, by.x = c("sample"), by.y = c("name"), all.y = TRUE)

nrow(meta)
[1] 1536
count(meta,quality)

Making titer plots

ggplot(filter(meta, DPI == "d02" | DPI == "d04" | DPI == "d06" |
                DPI == "d08" |DPI == "d10" | DPI == "d12"),
       aes(x = DPI, y = log10_titer, color = diet)) +
  geom_point() +
  geom_line(aes(group = ferretID)) +
  facet_grid(~inf_route) +
  PlotTheme1 +
  DietcolScale


# don't have titer information for W17 cohort (probably were never measured)
# don't have this info past day 6 for some ferrets sacrificed for pathology at St Jude's

m1 = filter(meta, titer != "NA" & titer != "sacrificed") %>%
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06" |
                DPI == "d08" | DPI == "d10" | DPI == "d12") %>%
  group_by(inf_route, diet, DPI,cohort) %>%
  mutate(avg_titer = mean(titer)) %>%
  mutate(avg_log_titer = mean(log10_titer)) %>%
  ungroup()

avg_titer = ggplot(filter(m1, inf_route == "Index" | inf_route == "Contact"), 
              aes(x = DPI, y = avg_log_titer, color = cohort)) +
  geom_point(size = 3) +
  geom_line(aes(group = cohort), size = 1.5) +
  facet_grid(diet~inf_route) +
  ylim(0,6) + 
  PlotTheme1 #+
#  DietcolScale
print(avg_titer)
ggsave("avg_titer.pdf", avg_titer, path = savedir, width = 10, height = 5)


m1_good = filter(meta, quality == "good") %>% 
  filter(titer != "NA" & titer != "sacrificed") %>%
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06" |
                DPI == "d08" | DPI == "d10" | DPI == "d12") %>%
  group_by(inf_route, diet, DPI) %>%
  mutate(avg_titer = mean(titer)) %>%
  mutate(avg_log_titer = mean(log10_titer)) %>%
  ungroup()

avg_titer_nozeroes = ggplot(filter(m1_good,inf_route == "Index" | inf_route == "Contact"), 
              aes(x = DPI, y = avg_log_titer, color = diet)) +
  geom_point(size = 3) +
  geom_line(aes(group = diet), size = 1.5) +
  facet_grid(~inf_route) +
  ylim(0,6) + 
  PlotTheme1 +
  DietcolScale
print(avg_titer_nozeroes)
ggsave("avg_titer_nozeroes.pdf",avg_titer_nozeroes,path = savedir,width = 7, height = 5)


m1_all = filter(meta, titer != "NA" & titer != "sacrificed") %>%
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06" |
                DPI == "d08" | DPI == "d10" | DPI == "d12") %>%
  group_by(diet, DPI) %>%
  mutate(avg_titer = mean(titer)) %>%
  mutate(avg_log_titer = mean(log10_titer)) %>%
  ungroup()

avg_titer_all = ggplot(filter(m1_all,inf_route == "Index" | inf_route == "Contact"), 
              aes(x = DPI, y = avg_log_titer, color = diet)) +
  geom_point(size = 3) +
  geom_line(aes(group = diet), size = 1.5) +
  ylim(0,6) + 
  PlotTheme1 +
  DietcolScale
print(avg_titer_all)


m1_all_good = filter(meta, quality == "good") %>% 
  filter(titer != "NA" & titer != "sacrificed") %>%
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06" |
                DPI == "d08" | DPI == "d10" | DPI == "d12") %>%
  group_by(diet, DPI) %>%
  mutate(avg_titer = mean(titer)) %>%
  mutate(avg_log_titer = mean(log10_titer)) %>%
  ungroup()

avg_titer_all_good= ggplot(filter(m1_all_good,inf_route == "Index" | inf_route == "Contact"), 
              aes(x = DPI, y = avg_log_titer, color = diet)) +
  geom_point(size = 3) +
  geom_line(aes(group = diet), size = 1.5) +
  ylim(0,6) + 
  PlotTheme1 +
  DietcolScale
print(avg_titer_all_good)

ggplot(filter(m1, DPI == "d02" | DPI == "d04" | DPI == "d06" |
                DPI == "d08" | DPI == "d10" | DPI == "d12"),
       aes(x = log10_titer, y = Ct_Mgene)) +
  geom_point() +
  xlim(0,8) +
  PlotTheme1


ggplot(filter(m1, log10_titer > 1), aes(x = log10_titer, y = Ct_Mgene)) +
  geom_point() +
  xlim(0,8) +
  PlotTheme1

ggplot(meta, aes(x = quality, y = log10_titer)) +
  geom_point()

ggplot(meta, aes(x = quality, y = Ct_Mgene)) +
  geom_point()


Ct_dist_plot = ggplot(meta, aes(x = Ct_Mgene, fill = quality)) +
  geom_histogram(binwidth = 1) +
  geom_vline(xintercept = 32, linetype = "dashed") +
  PlotTheme1 +
  ylab("Number of samples")
print(Ct_dist_plot)
ggsave("Ct_dist_plot.pdf",Ct_dist_plot,path = savedir, width = 7, height = 5)

Using Ct_Mgene = 32 as 1X genome copy cutoff

meta_Ct1 = filter(meta, Ct_Mgene < 32) %>%
  droplevels()
meta_Ct2 = filter(meta, Ct_Mgene > 32) %>%
  droplevels()
meta_Ct2$Ct_Mgene = 32

meta_Ct = rbind(meta_Ct1, meta_Ct2)

Adding genome copy number info

Ct32 = filter(meta_Ct, Ct_Mgene == 32)
Ct32$genomecopy = 1

Ct31 = filter(meta_Ct, Ct_Mgene <= 32 & Ct_Mgene > 31)
Ct31$genomecopy = 2

Ct30 = filter(meta_Ct, Ct_Mgene <= 31 & Ct_Mgene > 30)
Ct30$genomecopy = 4

Ct29 = filter(meta_Ct, Ct_Mgene <= 30 & Ct_Mgene > 29)
Ct29$genomecopy = 8

Ct28 = filter(meta_Ct, Ct_Mgene <= 29 & Ct_Mgene > 28)
Ct28$genomecopy = 16

Ct27 = filter(meta_Ct, Ct_Mgene <= 28 & Ct_Mgene > 27)
Ct27$genomecopy = 32

Ct26 = filter(meta_Ct, Ct_Mgene <= 27 & Ct_Mgene > 26)
Ct26$genomecopy = 64

Ct25 = filter(meta_Ct, Ct_Mgene <= 26 & Ct_Mgene > 25)
Ct25$genomecopy = 128

Ct24 = filter(meta_Ct, Ct_Mgene <= 25 & Ct_Mgene > 24)
Ct24$genomecopy = 256

Ct23 = filter(meta_Ct, Ct_Mgene <= 24 & Ct_Mgene > 23)
Ct23$genomecopy = 512

Ct22 = filter(meta_Ct, Ct_Mgene <= 23 & Ct_Mgene > 22)
Ct22$genomecopy = 1024

Ct21 = filter(meta_Ct, Ct_Mgene <= 22 & Ct_Mgene > 21)
Ct21$genomecopy = 2048
meta_Ct = rbind(Ct32,Ct31,Ct30,Ct29,Ct28,Ct27,Ct26,Ct25,Ct24,Ct23,Ct22,Ct21)
ggplot(meta_Ct, aes(x = Ct_Mgene, y = genomecopy)) +
  geom_point() +
  PlotTheme1

ggplot(meta_Ct, aes(x = log10_titer, y = genomecopy)) +
  geom_point()

Loading in variant files

varfile = "./varfiles/H9N2.VariantsOnly.0.01.200.csv"

# read and rearrange the data
vars = read.csv(file=varfile,header=T,sep=",",na.strings = c(''))
vars$name = vars$sample

Rearranging variant dataframe

vdf = ArrangeVarWRep(vars)
# already have replicate data in the varfiles from running CompareReps.v2.py script
vdf = vdf[!duplicated(vdf), ] %>% droplevels()
nrow(vdf)
[1] 1781

Filtering variant df by timo binocheck

vdf$binocheck = factor(vdf$binocheck, levels = c("False","R1","R2","True"))
vdf_bino = filter(vdf, binocheck != "False")
vdf_bino = vdf_bino[!duplicated(vdf_bino), ] %>% droplevels()
nrow(vdf_bino)
[1] 1166
# this really gets rid of a lot of variants (~1000)

vdf_nobino = filter(vdf, binocheck != "True")
vdf_nobino = vdf_nobino[!duplicated(vdf_nobino), ] %>% droplevels()
nrow(vdf_nobino)
[1] 897
range(vdf_nobino$minorfreq)
[1] 0.01002194 0.49326611
ggplot(vdf_nobino, aes(x = minorfreq)) +
  geom_histogram(binwidth = 0.01) +
  PlotTheme1

Filtering variant df with frequency cutoffs

vdf = filter(vdf, minorfreq1 >= freq_cut & 
               minorfreq2 >= freq_cut & 
               minor %in% ntlist &
               major %in% ntlist) %>% 
            droplevels()
# based on MAF study, reps and 0.01% cutoff was best combo
#filter each replicate separately rather than using the average

vdf = vdf[!duplicated(vdf), ] %>% droplevels()
nrow(vdf)
[1] 1702
# does not eliminate any variants here

Adding metadata

vdf = merge(vdf,meta, by = c("sample","segment"))
vdf = vdf[!duplicated(vdf), ] %>% droplevels()

vdf$segment = factor(vdf$segment, levels = SEGMENTS)

vdf = filter(vdf, inf_route == "Index" | inf_route == "Contact" | inf_route == "Control")
# ignoring aerosol for now
vdf = filter(vdf, quality == "good")
vdf = vdf[!duplicated(vdf), ] %>% droplevels()

good_names = c(levels(factor(vdf$sample)))

SNVs correlated to titer?

vdf_count = group_by(vdf, sample, cohort, ferretID,DPI, inf_route, diet, STRAIN, resequenced, quality) %>%
  tally()
titer = select(meta, sample, titer)

vdf_count_titer = merge(vdf_count,titer, by = c("sample"))
vdf_count_titer = vdf_count_titer[!duplicated(vdf_count_titer), ]

vdf_count_titer$log10titer = log10(vdf_count_titer$titer)
vdf_count_titer$titer[is.na(vdf_count_titer$titer)] = 0
vdf_count_titer$log10titer[is.na(vdf_count_titer$log10titer)] = 0


vdf_count_titer_plot = ggplot(filter(vdf_count_titer, inf_route == "Index" | inf_route == "Contact"), 
                              aes(x = log10titer, y = n, color = diet)) +
  geom_point() +
  xlim(0,7.5) +
  geom_smooth(method = "glm") +
  facet_grid(~inf_route) +
  PlotTheme1 +
  DietcolScale
print(vdf_count_titer_plot)
ggsave("vdf_count_titer_plot.pdf",vdf_count_titer_plot,path = savedir, width = 7, height = 5)

Tallying number of ferrets with variants

fercount = select(vdf,sample,ferretID,DPI,diet,inf_route)
fercount = fercount[!duplicated(fercount), ]  %>% 
  unique() %>% 
  group_by(sample,diet,inf_route,DPI) %>% 
  tally()

# Counting the number of ferrets with variants, just by ferretID not DPI
filter(vdf, diet == "Lean" & inf_route == "Index") %>% count(ferretID)
filter(vdf, diet == "Obese" & inf_route == "Index") %>% count(ferretID)
filter(vdf, diet == "Lean" & inf_route == "Contact") %>% count(ferretID)
filter(vdf, diet == "Obese" & inf_route == "Contact") %>% count(ferretID)

Plotting ferret tally

ggplot(fercount, aes(x = DPI, y = n, fill = diet)) +
  geom_col(position = "stack") +
  facet_grid(~inf_route) +
  ylab("Number of Ferrets with SNVs") +
  PlotTheme3 +
  DietcolScale_fill


snv_count = group_by(filter(vdf, inf_route == "Index" | inf_route == "Contact"), sample, ferretID, DPI,inf_route,diet) %>%
  tally() %>%
  ggplot(., aes(x = n, fill = diet)) +
  geom_histogram(binwidth = 5) +
  facet_grid(diet~inf_route) +
  xlab("Number of variants") +
  ylab("Number of ferrets") +
  PlotTheme1 +
  DietcolScale_fill
print(snv_count)
ggsave("SNVs_per_ferret.pdf",snv_count,path = savedir, width = 9, height = 5)

transmission_info = "/Users/marissaknoll/Desktop/GitHub/Obesity/NewExtractions/H9N2/TransmissionPairs.csv"
pairs = read.csv(transmission_info, header = T)

fercount = separate(fercount,sample,into = c("ferretID","DPI"))
fercount = merge(fercount, pairs, by = c("ferretID"))

  
p1 = fercount %>% unique() %>% 
    ggplot(., aes(x= DPI, y = pair_numbers, fill = diet)) + 
    geom_tile(color = 'black') + 
    PlotTheme3 +
    DietcolScale_fill + 
    facet_grid(pair_diets~inf_route, scales = 'free', space = 'free')
print(p1)
ggsave("ferrets_tileplot.pdf", p1, path = savedir,)
Saving 7.29 x 4.51 in image

m2 = filter(meta, titer != "NA" & titer != "sacrificed") %>%
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06" | DPI == "d08" | DPI == "d10" | DPI == "d12")
titers_pairs = merge(m2,pairs, by = c("ferretID"), all.x = TRUE)

titers_pairs = group_by(titers_pairs,inf_route, diet, DPI,pair_diets) %>%
  mutate(avg_titer = mean(titer)) %>%
  mutate(sd_titer = sd(titer)) %>%
  mutate(avg_log_titer = mean(log10_titer)) %>%
  ungroup()

titers_pairs_plot = ggplot(titers_pairs, aes(x = DPI, y = avg_log_titer, color = diet)) +
  geom_point() +
  geom_line(aes(group = inf_route)) +
  geom_hline(aes(yintercept = 1)) +
  facet_grid(inf_route+diet~pair_diets) +
  DietcolScale +
  ylim(0,8) +
  PlotTheme1
print(titers_pairs_plot)
ggsave("titers_pairs_plot.pdf",titers_pairs_plot,path=savedir)
Saving 7.29 x 4.51 in image

Plotting rep1 vs rep2

rep_correlation = ggplot(vdf) +
  geom_point(aes(x = minorfreq1, y = minorfreq2)) +
  geom_point(aes(x = majorfreq1, y = majorfreq2)) +
  PlotTheme1 +
  xlab("Allele frequency in replicate 1") +
  ylab("Allele frequency in replicate 2") +
  xlim(0,0.55) + ylim(0,0.55)
print(rep_correlation)
ggsave("rep_correlation.pdf",rep_correlation,path = savedir)
Saving 7.29 x 4.51 in image

Consensus changes

con_change = filter(vdf, stocknt != major) %>%
  filter(major %in% ntlist)
con_change = con_change[!duplicated(con_change), ]
nrow(con_change)
[1] 11
con_change$maj = paste0(con_change$segment,"_",con_change$stock,con_change$ntpos)
con_change$ferretID_maj = paste0(con_change$ferretID,"_",con_change$maj)
con_change = con_change[!duplicated(con_change$ferretID_maj),] 
# not counting same consensus change but just on different days - basically counting unique consensus changes

nrow(con_change)
[1] 10
cons = count(con_change,ferretID,diet,inf_route)

select(con_change, stocknt, major, minor)
# in all cases, the stocknt is the minor -> has been replaced by another nt
# did these arise as minors first?

Plotting consensus changes

con_change$var = paste0(con_change$ferretID,"_",con_change$segment,"_",
                        con_change$major,"_",con_change$ntpos,"_",con_change$minor)
consensus = unique(con_change$var)
length(consensus)
[1] 10
vdf$var = paste0(vdf$ferretID,"_",vdf$segment,"_",vdf$major,"_",vdf$ntpos,"_",vdf$minor)

minorvdf = filter(vdf, !(var %in% consensus))
minorvdf = minorvdf[!duplicated(minorvdf), ]
nrow(vdf) - nrow(minorvdf)

Loading in tranmission data

transmission = "./TransmissionPairs.csv"
pairs = read.csv(file = transmission, header = T, sep = ",")

vdf_pairs = merge(vdf, pairs, by = c("ferretID"))

Can the consensus changes be detected as minor variants first?

Tallying SNVs

# can make these groupings whatever you want

# count the number of SNVs per sample
group_list_seg = c('ferretID','segment',"DPI","diet","inf_route","cohort") # counts across each segment 
group_list_gen = c('ferretID',"DPI","diet","inf_route","cohort") # Counts across entire genome

seg_count = TallyIt(minorvdf, group_list_seg, "snv_count")
gen_count = TallyIt(minorvdf, group_list_gen, "snv_count") 
# INCLUDING SEGMENTS WITH NO SNVS - but only using those that passed seq cutoff
reseq_seg = select(meta,ferretID,segment,DPI,diet,inf_route,cohort, quality) %>% 
  filter(quality == "good") %>% 
  unique()
seg_count = merge(seg_count,reseq_seg, all= TRUE)
seg_count = seg_count[!duplicated(seg_count), ]

seg_count$snv_count[is.na(seg_count$snv_count)] = 0
seg_count = filter(seg_count, !is.na(ferretID))
reseq_gen = select(meta,ferretID,DPI,diet,inf_route,cohort,quality) %>% 
  filter(quality == "good") %>% 
  unique()
gen_count = merge(gen_count,reseq_gen, all = TRUE)
gen_count = gen_count[!duplicated(gen_count), ]

gen_count$snv_count[is.na(gen_count$snv_count)] = 0
gen_count = filter(gen_count, !is.na(ferretID))
# Average Number of Variants per Sample
gen_count_avg = group_by(gen_count, DPI, diet, inf_route) %>%
  mutate(avgSNV = mean(snv_count), sdSNV = sd(snv_count))

seg_count_avg = group_by(seg_count, DPI, diet) %>%
  mutate(avgSNV = mean(snv_count), sdSNV = sd(snv_count))

Calculating Shannon Entropy

minorvdf = ShannonPos(minorvdf)
minorvdf$SegmentSize = as.numeric(minorvdf$SegmentSize)
minorvdf$shannon_perkb = (minorvdf$segment_shan/(minorvdf$SegmentSize/1000))
minorvdf$normalized_shannon = (minorvdf$shannon/GenomeSize)
# shannon_ntpos = shannon entropy at that nt pos - should always be between 0 and 1 for each sample
# segment_shan = sum of all nt_pos per segment for each sample
# shannon = sum of all segment_shan across genome for each sample
# shannon_perkb = segment shannon per kb (segment specific) for each sample
# normalized_shannon = shannon divided by genome size (can make per kb by dividing by 1000) for each sample

Test for significance

o = filter(shan_g, DPI == "Stock" & diet == "Control")
l = filter(shan_g, DPI == "d06" & diet == "Lean")
t.test(o$normalized_shannon,l$normalized_shannon)

    Welch Two Sample t-test

data:  o$normalized_shannon and l$normalized_shannon
t = -2.2818, df = 3.4861, p-value = 0.09442
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.0036431032  0.0004625781
sample estimates:
  mean of x   mean of y 
0.001449201 0.003039464 
shan_g_avg = group_by(shan_g, DPI, diet, inf_route) %>% 
  mutate(avgShan = mean(normalized_shannon), sdShan = sd(normalized_shannon))
shan_segkb = ungroup(minorvdf) %>%
  select(ferretID, DPI, diet, inf_route, segment, shannon_perkb)
shan_segkb = shan_segkb[!duplicated(shan_segkb),]
shan_segkb_avg = group_by(shan_segkb, DPI, diet, inf_route, segment) %>% 
  mutate(avgShan = mean(shannon_perkb), sdShan = sd(shannon_perkb)) 
# gives a genome-wide average of normalized segment shannnons for every sample

Making plots for variant tallies and Shannon entropy

VarPlot = ggplot(gen_count_avg, aes(x=DPI, fill = diet)) +
  geom_col(aes(y = avgSNV, group = diet), position = "dodge") +
  geom_jitter(aes(group = diet, y = snv_count), width  = 0.15, size = 2) +
  geom_errorbar(aes(ymin = avgSNV - sdSNV,
                    ymax = avgSNV + sdSNV)) +
  ylab("Average number of SNVs per sample") +
  xlab("Days after infection") +
  facet_grid(~inf_route+diet) +
  PlotTheme1 +
  DietcolScale_fill
print(VarPlot)
ggsave(VarPlot, file = "VariantCount.pdf", path = savedir, width = 25, height = 10)
ShannonPlot = ggplot(shan_g_avg, aes(x=DPI, fill = diet)) +
  geom_col(aes(y = avgShan, group = diet), position = "dodge") + #plots average
  geom_jitter(aes(y = normalized_shannon, group = diet), width  = 0.15) + #plots value for each sample
  geom_errorbar(aes(ymin = avgShan - sdShan,
                    ymax = avgShan + sdShan)) +
  ylab("Average Shannon entropy per site across genome") +
  facet_grid(~inf_route+diet) +
  PlotTheme1 +
  DietcolScale_fill
print(ShannonPlot)
ggsave(ShannonPlot, file = "MeanShanPerSite.pdf", path = savedir)

ShannonPlot2 = ggplot(shan_segkb_avg, aes(x=DPI, fill = diet)) +
  geom_col(aes(y = avgShan, group = diet), position = "dodge") + # plots average
  #geom_point(aes(y = shannon_perkb, group = diet)) + # plots value for each segment, sample
  #geom_errorbar(aes(ymin = avgShan - sdShan,
  #                  ymax = avgShan + sdShan)) +
  ylab("Average Shannon entropy per kB across segments") +
  facet_grid(~segment) +
  PlotTheme1 +
  DietcolScale_fill
print(ShannonPlot2)
ggsave(ShannonPlot2, file = "MeanShanPerSegKB.pdf", path = savedir)
shan_seg_plot = filter(shan_segkb, inf_route == "Index") %>% 
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06") %>%
  ggplot(. , aes(x = segment, y = shannon_perkb, color = diet)) +
  geom_boxplot() +
  facet_grid(~DPI) +
  PlotTheme1 +
  ylab("Shannon entropy per kb across each segment") +
  DietcolScale
print(shan_seg_plot)
ggsave("shan_seg_plot.pdf",shan_seg_plot,path=savedir, width = 10, height = 5)

shan_gen_plot = filter(shan_g_avg, inf_route == "Index" | inf_route == "Control") %>% 
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06" | DPI == "d08" | DPI == "Stock") %>%
  ggplot(. , aes(x = diet, y = (normalized_shannon/1000), color = diet)) +
  geom_boxplot() +
  geom_jitter(width = 0.1) +
  facet_grid(~DPI) +
  PlotTheme1 +
  ylab("Shannon entropy per kb across each genome") +
  DietcolScale
print(shan_gen_plot)
ggsave("shan_gen_plot.pdf",shan_gen_plot,path = savedir, width = 10, height = 5)

T tests for plots

o = filter(shan_segkb, inf_route == "Index" & DPI == "d02" & diet == "Obese" & segment == "H9N2_NS")
l = filter(shan_segkb, inf_route == "Index" & DPI == "d02" & diet == "Lean" & segment == "H9N2_NS")
t.test(o$shannon_perkb,l$shannon_perkb)

# On day 4, there is significantly higher diversity in NP in lean ferrets (p = 0.06339)
# On day 4, there is significantly higher diversity in MP in lean ferrets (p = 0.09573)
# On day 4, there is significantly higher diversity in NS in lean ferrets (p = 0.004744)

# On day 6, there is significantly higher diversity in NA in lean ferrets (p = 0.008199)
o = filter(shan_g_avg, inf_route == "Index" & DPI == "d06" & diet == "Obese")
l = filter(shan_g_avg, inf_route == "Index" & DPI == "d06" & diet == "Lean")
t.test(o$normalized_shannon,l$normalized_shannon)

# On day 6, there is significantly higher diversity (Shannon/kb for each genome) in lean ferrets (p = 0.05607)
gen_count_avg = filter(gen_count_avg, inf_route == "Index" | inf_route == "Contact")
LeanSNVs_perFerret = ggplot(filter(gen_count_avg, diet == "Lean" & DPI != "d12"),
                             aes(x = DPI, y = snv_count, color = ferretID)) +
  geom_point() +
  geom_line(aes(group = ferretID)) +
  ylim(0,45) +
  facet_grid(~diet+inf_route)+ 
  PlotTheme1 
print(LeanSNVs_perFerret)
ggsave("LeanSNVs_perFerret.png", LeanSNVs_perFerret, path = savedir, width = 10, height = 5)

ObeseSNVs_perFerret = ggplot(filter(gen_count_avg, diet == "Obese"),
                              aes(x = DPI, y = snv_count, color = ferretID)) +
  geom_point() +
  geom_line(aes(group = ferretID)) +
    ylim(0,45) +
  facet_grid(~diet+inf_route) + 
  PlotTheme1
print(ObeseSNVs_perFerret)
ggsave("ObeseSNVs_perFerret.png", ObeseSNVs_perFerret, path = savedir, width = 10, height = 5)

Test for significance

o = filter(gen_count, inf_route == "Index" & DPI == "d06" & diet == "Obese")
l = filter(gen_count, inf_route == "Index" & DPI == "d06" & diet == "Lean")
t.test(o$snv_count,l$snv_count)

    Welch Two Sample t-test

data:  o$snv_count and l$snv_count
t = -1.4582, df = 1.6188, p-value = 0.3088
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -62.63952  36.13952
sample estimates:
mean of x mean of y 
    18.00     31.25 

Norm snv_count by titer

avg_titer_df = select(meta, ferretID, DPI, inf_route, diet, titer, log10_titer) %>%
  filter(!is.na(titer)) %>%
  droplevels()
avg_titer_df = avg_titer_df[!duplicated(avg_titer_df), ]
  
seg_count_titer = merge(seg_count, avg_titer_df, by = c("ferretID","DPI","diet","inf_route"))
seg_count_titer$norm_snv = seg_count_titer$snv_count / seg_count_titer$log10_titer

seg_count_titer1 = filter(seg_count_titer, norm_snv == "NaN")
seg_count_titer1$norm_snv = 0
seg_count_titer2 = filter(seg_count_titer, norm_snv != "NaN")

seg_count_titer = rbind(seg_count_titer1,seg_count_titer2)
snv_count_seg_titer_plot = filter(seg_count_titer, inf_route == "Index") %>% 
  filter(DPI == "d02" | DPI == "d04" | DPI == "d06") %>%

ggplot(. , aes(x = segment, y = norm_snv, color = diet)) +
  geom_boxplot() +
  #geom_point() +
  facet_grid(~DPI) +
  PlotTheme1 +
  DietcolScale
print(snv_count_seg_titer_plot)
ggsave("snv_count_seg_titer_plot.pdf", snv_count_seg_titer_plot, path = savedir, width = 10, height = 5)

Trying to do average snv count per ferret within a diet_pairs group

#minorvdf_pairs = merge(minorvdf, pairs, by = c("ferretID"))

#group_list_pairs = c('ferretID',"DPI","diet","inf_route","cohort",'pair_diets') # counts across each segment 
#pairs_count = TallyIt(minorvdf_pairs, group_list_pairs, "snv_count")

#pairs_count = merge(pairs_count,reseq_gen, all = TRUE)
#pairs_count = pairs_count[!duplicated(pairs_count), ]

#pairs_count_avg = group_by(pairs_count, DPI, diet, inf_route,pair_diets) %>%
#  mutate(avgSNV = mean(snv_count), sdSNV = sd(snv_count))
print(gen_pairs_plot)
Error in print(gen_pairs_plot) : object 'gen_pairs_plot' not found

Genetic distance measure

distvars = read.csv("/Users/marissaknoll/Desktop/GitHub/Obesity/NewExtractions/H9N2/varfiles/H9N2.VariantPositions.AcrossSamples.0.01.200.csv", header = T)
distvars = distvars[!duplicated(distvars), ] %>% filter(sample %in% good_names)
gd2 = select(distvars,sample,segment,ntpos,nt,freq) %>% filter(sample %in% good_names) #MARISSA CHECK THIS - WHY DON'T THE GOOD NAMES MATCH
gd2$sample = paste0('f', gd2$sample)

gd2 = gd2 %>% filter(nt != "-") %>%
  group_by(sample, segment) %>%
  pivot_wider(names_from = nt, values_from = freq, id_cols = c(sample, segment, ntpos), values_fill = 0) %>%
  arrange(segment,ntpos)

gd2 = gd2[!duplicated(gd2),] %>% droplevels() # remove any dups

gd2$positions = paste0(gd2$segment,'_', gd2$ntpos)
positions = c(levels(factor(gd2$positions)))

gd2 = filter(gd2, sample != "f1415_d02")
filter(gd2, positions == "H9N2_PB2_984")
filter(distvars, ntpos == "984")
gd2 = gd2 %>% group_by(sample) %>%
mutate(sample_count = n()) %>%
ungroup() %>% filter(sample_count == 686) %>% unique()

gd2 %>% select(sample_count,sample) %>% unique() %>% group_by(sample_count) %>% tally() # trying to determine positions that passed cutoff -> figure out why this isn't all of them (eventually)
# Kate thinks it is python code in generating .csv, specifically the totalcount (major cutoff) not passing a threshold

set1 = unique(factor(gd2$sample)) #check to make sure everything is the same size throughout

dist_prep = as.data.frame(gd2) %>% select(-ntpos, -segment,-sample_count) %>% unique()

for (pos in positions){
  
  dist_orig = matrix(data = 0, nrow = length(set1) , ncol = length(set1)) # generate empty matrix to add dist numbers to

  rownames(dist_orig) = set1
  colnames(dist_orig) = set1
  
  d1 = dist_prep %>% filter(positions == pos) %>% unique()
  
  rownames(d1) = d1$sample # make rownames the sample names
  d1[,1] = NULL # remove the row names columns (which is the first column selected)
  
  D_man = dist(d1, method="manhattan") # manhattan distance = L1 norm
  D_man = as.matrix(D_man) #change dist type to matrix
  
  # check to make sure dist_orig and dist_euc are in same order
  # change order of dist_orig to order of dist_euc
  dist_orig = dist_orig[rownames(D_man), ]
  dist_orig = dist_orig[,colnames(D_man)]
  
  if(identical(dimnames(dist_orig), dimnames(D_man)) == TRUE){
    
      dist_man <- dist_orig + D_man #add to the overall matrix
    
  }else{
    
    print("dimnames are off")
    
  }
  
}
Warning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercion
for (pos in positions){
  
  dist_orig = matrix(data = 0, nrow = length(set1) , ncol = length(set1)) # generate empty matrix to add dist numbers to

  rownames(dist_orig) = set1
  colnames(dist_orig) = set1
  
  d1 = dist_prep %>% filter(positions == pos) %>% unique()
  
  rownames(d1) = d1$sample # make rownames the sample names
  d1[,1] = NULL # remove the row names columns (which is the first column selected)
  
  d1 = d1[order(row.names(d1)),] # order the rows
  
  D_euc = dist(d1, method="euclidean") # euclidean disatnce = L2 norm
  D_euc = as.matrix(D_euc) #change dist type to matrix
  
  # check to make sure dist_orig and dist_euc are in same order
  # change order of dist_orig to order of dist_euc
  dist_orig = dist_orig[rownames(D_euc), ]
  dist_orig = dist_orig[,colnames(D_euc)]
  
  if(identical(dimnames(dist_orig), dimnames(D_euc)) == TRUE){
    
      dist_euc <- dist_orig + D_euc #add to the overall matrix
    
  }else{
    
    print("dimnames are off")
    
  }
  
}
Warning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercionWarning: NAs introduced by coercion
meta$name = paste0("f",meta$sample)
red_meta = select(meta, name,cohort,ferretID,DPI,inf_route,diet)

# Manhattan distances (L1 norm)
man_df = as.data.frame(dist_man)
man_df$sample = rownames(man_df)

man_long = man_df %>%
  pivot_longer(!sample, names_to = c("comp"), values_to = "dist")
man_long = man_long[!duplicated(man_long), ] %>% droplevels()

man_long_m = merge(red_meta, man_long, by.x = c("name"), by.y = c("sample"))
man_long_m = man_long_m[!duplicated(man_long_m), ] %>% droplevels()

# Euclidian distances (L2 norm)
euc_df = as.data.frame(dist_euc)
euc_df$sample = rownames(euc_df)

euc_long = euc_df %>%
  pivot_longer(!sample, names_to = c("comp"), values_to = "dist")
euc_long = euc_long[!duplicated(euc_long), ] %>% droplevels()

euc_long_m = merge(red_meta, euc_long, by.x = c("name"), by.y = c("sample"))
euc_long_m = euc_long_m[!duplicated(euc_long_m), ] %>% droplevels()

Merge again so we have info for both samples in a comparison

man_long = merge(red_meta, man_long_m, by.x = c("name"), by.y = c("comp"))
man_long = man_long[!duplicated(man_long), ] %>% droplevels()

euc_long = merge(red_meta, euc_long_m, by.x = c("name"), by.y = c("comp"))
euc_long = euc_long[!duplicated(euc_long), ] %>% droplevels()
L1_stock_index = ggplot(filter(man_long, inf_route.x == "Control" & 
                inf_route.y == "Index" &
                cohort.x == cohort.y)) +
  geom_boxplot(aes(x = diet.y, y = dist), outlier.shape =  NA, width = 0.5) +
  geom_jitter(aes(x = diet.y, y = dist, group = diet.y, color = diet.y), width = 0.1) +
  facet_grid(~DPI.y,scales = 'free', space ='free') +
  ggtitle("L1-norm between index samples and stock") +
  xlab("Diet of index ferret") +
  ylab("L1-norm (Man. distance)") +
  PlotTheme1 +
  DietcolScale
print(L1_stock_index)
ggsave("L1_stock_index.pdf",L1_stock_index,path = savedir)
Saving 7.29 x 4.51 in image

L2_stock_index = ggplot(filter(euc_long, inf_route.x == "Control" & 
                inf_route.y == "Index" &
                cohort.x == cohort.y)) +
  geom_boxplot(aes(x = diet.y, y = dist), outlier.shape =  NA, width = 0.5) +
  geom_jitter(aes(x = diet.y, y = dist, group = diet.y, color = diet.y), width = 0.1) +
  facet_grid(~DPI.y,scales = 'free', space ='free') +
  ggtitle("L1-norm between index samples and stock") +
  xlab("Diet of index ferret") +
  ylab("L2-norm (Euc. distance)") +
  PlotTheme1 +
  DietcolScale
print(L2_stock_index)
ggsave("L2_stock_index.pdf",L2_stock_index,path = savedir)
Saving 7.29 x 4.51 in image

# T tests
ob_d06 = filter(man_long, inf_route.x == "Control" & inf_route.y == "Index" &
                  cohort.x == cohort.y &
                  diet.y == "Obese" & DPI.y == "d06")
ln_d06 = filter(man_long, inf_route.x == "Control" & inf_route.y == "Index" &
                  cohort.x == cohort.y &
                  diet.y == "Lean" & DPI.y == "d06")
t.test(ob_d06$dist,ln_d06$dist)
man_long_pair = merge(man_long, pairs, by.x = c("ferretID.x"), by.y = c("ferretID"))
man_long_p = merge(man_long_pair, pairs, by.x = c("ferretID.y"), by.y = c("ferretID"))
stock_index = filter(man_long, inf_route.x == "Control" & inf_route.y == "Index" & cohort.x == cohort.y) %>%
  mutate(cat = "Stock -> Index",
         group = "Stock") %>%
  mutate(pair_numbers.x = NA,
         pair_diets.x = NA,
         pair_numbers.y = NA,
         pair_diets.y = NA) %>%
  select(-c("group"))
index_contact_pairs = filter(man_long_p, inf_route.x == "Index" & inf_route.y == "Contact" & pair_numbers.x == pair_numbers.y) %>%
  mutate(cat = "Index -> Contact (Pairs)")
# 10 LN -> LN, 2 LN -> OB, 26 OB -> OB
index_contact_notpairs = filter(man_long_p, inf_route.x == "Index" & inf_route.y == "Contact" & pair_numbers.x != pair_numbers.y) %>%
  mutate(cat = "Index -> Contact (Not Pairs)")

man_comps = rbind(stock_index, index_contact_pairs, index_contact_notpairs)
man_comps$cat = factor(man_comps$cat, levels = c("Stock -> Index","Index -> Contact (Pairs)","Index -> Contact (Not Pairs)"))

ggplot(man_comps) +
  geom_boxplot(aes(x = cat, y = dist, color = diet.y), outlier.shape =  NA, width = 0.5) +
#  geom_jitter(aes(x = cat, y = dist, group = diet.y, color = diet.y), width = 0.1) +
  ggtitle("L1-norm between index samples and stock") +
  xlab("Comparison") +
  ylab("L1-norm (Man. distance)") +
  PlotTheme1 +
  DietcolScale

# the outliers are all comparisons to 1415_d02 which is weird

ggplot(filter(man_long, inf_route.x == "Index" &
                inf_route.y == "Contact" &
                pair_numbers.x == pair_numbers.y)) +
  geom_boxplot(aes(x = pair_number.x, y = dist), outlier.shape =  NA, width = 0.5) +
  geom_jitter(aes(x = diet.y, y = dist, group = diet.y, color = diet.x), width = 0.1) +
  #facet_grid(~DPI.y,scales = 'free', space ='free') +
  ggtitle("L1-norm between index samples and everything but their contacts") +
  xlab("Diet of contact ferret") +
  ylab("L1-norm (Man. distance)") +
  PlotTheme1 +
  DietcolScale

Stock to Index Day 2 comparisons (Stock -> Lean, Stock -> Obese)

ggplot(filter(dist_long_m, cohort == "W17", comp == "fW17_HK1073", inf_route == "Index", DPI == "d02"), 
       aes(x = diet, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1) +
  PlotTheme1
# had to filter by comp so the individual samples would keep their metadata

ggplot(filter(dist_long_m, cohort == "F17", comp == "fF17_HK1073", inf_route == "Index", DPI == "d02"), 
       aes(x = diet, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1) +
  PlotTheme1

ggplot(filter(dist_long_m, cohort == "Sm18", comp == "fSm18_HK1073", inf_route == "Index", DPI == "d02"), 
       aes(x = diet, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1) +
  PlotTheme1

ggplot(filter(dist_long_m, cohort == "Sp20", comp == "fSp20_HK1073", inf_route == "Index", DPI == "d02"), 
       aes(x = diet, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1) +
  PlotTheme1
# no samples from this cohort found

#Sp19 samples are good, the stock is missing -> not in good samples

#compare stock -> index over DPI (expectation is more distant over time)

ggplot(filter(dist_long_m, cohort == "W17", comp == "fW17_HK1073", inf_route == "Index"), 
       aes(x = DPI, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1, aes(color = diet)) +
  PlotTheme1

ggplot(filter(dist_long_m, cohort == "F17", comp == "fF17_HK1073", inf_route == "Index"), 
       aes(x = DPI, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1, aes(color = diet)) +
  PlotTheme1

ggplot(filter(dist_long_m, cohort == "Sm18", comp == "fSm18_HK1073", inf_route == "Index"), 
       aes(x = DPI, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1, aes(color = diet)) +
  PlotTheme1

Add transmission data #compare lean -> lean transmission #compare d02 index -> all contact time points (do the contacts diverge from their donors over time) #compare last time point index - last time point contact

ggplot(filter(dist_long_pairs, cohort.x == "Sm18" & cohort.y == "Sm18" & pair_numbers.x == pair_numbers.y, dist > 0), 
       aes(x = inf_route.x, y = dist)) +
  geom_boxplot() +
  geom_jitter(width = 0.1, aes(color = diet.x)) +
  facet_grid(~pair_diets.x) +
  PlotTheme1

Do the number of variants correlate with Ct?

meta_small = select(meta,"ferretID","DPI","diet","inf_route","cohort","Ct_Mgene")
varcount = merge(gen_count_avg, meta_small, by = c("ferretID","DPI","diet","inf_route","cohort"))

ggplot(varcount, aes(x = Ct_Mgene, y = snv_count, color = diet)) +
  geom_point() +
  geom_smooth(method = "glm") +
  #ylim(20,30) +
  facet_grid(~inf_route) +
  PlotTheme1 +
  DietcolScale
# will get a warning when NAs are removed

CT_SNVcount_plot = ggplot(filter(varcount, inf_route != "Control"), aes(x = Ct_Mgene, y = snv_count)) +
  geom_point() +
  geom_smooth(method = "glm") +
  #ylim(20,30) +
  facet_grid(~inf_route) +
  PlotTheme1 +
  DietcolScale
print(CT_SNVcount_plot)
ggsave("CT_SNVcount_plot.pdf",CT_SNVcount_plot,path = savedir, width = 10, height = 5)
#SNVs_Titer = ggplot(gen_count, aes(x = log10_titer, y = snv_count, color = diet)) +
#  geom_point(aes(shape = DPI)) +
#  geom_smooth(method = "glm") +
#  PlotTheme1 +
#  DietcolScale +
#  xlim(0,7) +
#  facet_grid(~inf_route)
#print(SNVs_Titer)
#ggsave("SNVs_Titer.pdf",SNVs_Titer,path = savedir, width = 8, height = 5)
#ggsave("SNVs_Titer.png",SNVs_Titer,path = savedir, width = 8, height = 5)

# There are 16 points in the index ferrets with LogTiter < 3 in Index ferrets -> 2 samples (w/ 8 segments)
# Are these outliers that a skewing the data?

#PossOutliers = filter(var_titers, inf_route == "Index" & diet == "Lean" & LogTiter < 3)
#outlierSamps = levels(factor(PossOutliers$Sample))

#var_titers_NoOut = var_titers %>% filter(!(Sample %in% outlierSamps))

#SNVs_Titer_NoOut = ggplot(var_titers_NoOut, aes(x = LogTiter, y = snv_count, color = diet)) +
#  geom_point(aes(shape = DPI)) +
#  geom_smooth(method = "glm") +
#  PlotTheme1 +
#  DietcolScale +
#  xlim(0,7) +
#  facet_grid(~inf_route)
#print(SNVs_Titer_NoOut)

# NVs_Titer_NoDiet = ggplot(var_titers, aes(x = LogTiter, y = snv_count)) +
#  geom_point(aes(shape = DPI)) +
#  geom_smooth(method = "glm") +
#  PlotTheme1 +
#  DietcolScale +
#  xlim(0,7) +
#  facet_grid(~inf_route)
#print(SNVs_Titer_NoDiet)
#meta_smaller = select(meta_small,c(ferretID, DPI, diet, inf_route))
#meta_smaller = meta_smaller[!duplicated(meta_smaller), ]

#titers_H9_meta = merge(titers_H9, meta_smaller, by = c("ferretID", "DPI","diet","inf_route"))
#titers_H9_meta = titers_H9_meta[!duplicated(titers_H9_meta), ]

#titers_H9_meta = titers_H9_meta[!duplicated(titers_H9_meta), ]
#titers_H9_meta$Titer[is.na(titers_H9_meta$Titer)] = 0
#titers_H9_meta = filter(titers_H9_meta, Titer > 0)

#AvgTiters = group_by(titers_H9_meta, diet, inf_route,DPI) %>%
#  mutate(LogTiter = log10(Titer)) %>% 
#  mutate(avgTiter = mean(LogTiter), sdTiter = sd(LogTiter))
#AvgTiters$inf_route = factor(AvgTiters$inf_route, levels = c("Index","Contact"))

#TiterPlot = ggplot(AvgTiters, aes(x = DPI, y = avgTiter, color = diet)) +
#  geom_point() +
#  geom_line(aes(group = diet)) +
#  geom_errorbar(aes(ymin = avgTiter - sdTiter,
#                    ymax = avgTiter + sdTiter)) +
#  ylim(0,7) +
#  facet_grid(~inf_route) +
#  DietcolScale +
#  PlotTheme1
#print(TiterPlot)
#ggsave("TiterPlot.png", TiterPlot, width = 7, height = 5, path = savedir)

#titers_H9_meta$inf_route = factor(titers_H9_meta$inf_route, levels = c("Index","Contact"))

#AllTitersPlot = ggplot(titers_H9_meta, aes(x = DPI, y = log10(Titer), color = as.character(ferretID))) +
#  geom_point(size = 3) +
#  geom_line(aes(group = ferretID), size = 1.5) +
#  ylim(0,7) +
#  facet_grid(diet~inf_route) +
#  PlotTheme1
#print(AllTitersPlot)
#ggsave("AllTitersPlot.png", AllTitersPlot, width = 14, height = 7, path = savedir)

dNdS analysis

# by ferret
dNdS_ferret = minorvdf %>% 
  ungroup() %>% 
  group_by(ferretID,DPI,diet,inf_route) %>% 
  count(nonsyn)

dNdS_ferret = pivot_wider(dNdS_ferret,names_from = nonsyn, values_from = n)
dNdS_ferret = select(dNdS_ferret, ferretID,DPI,nonsyn,syn)
dNdS_ferret$dNdS = paste0(dNdS_ferret$nonsyn / dNdS_ferret$syn)
dNdS_ferret$dNdS = as.numeric(dNdS_ferret$dNdS)

dNdS_ferret = filter(dNdS_ferret, inf_route == "Index" | inf_route == "Contact")

dNdS_ferret_plot = ggplot(dNdS_ferret, aes(x = DPI, y = dNdS, color = ferretID)) +
  geom_point() +
  geom_line(aes(group = ferretID)) +
  facet_grid(~diet+inf_route) +
  PlotTheme1
print(dNdS_ferret_plot)
ggsave("dNdS_ferret.pdf", dNdS_ferret_plot, path = savedir)
ggsave("dNdS_ferret.png", dNdS_ferret_plot, path = savedir, width = 10, height = 5)
# by ferret and gene
#dNdS_ferret_gene = minorvdf %>% 
#  ungroup() %>% 
#  group_by(ferretID,DPI,diet,inf_route,segment) %>% 
#  count(nonsyn)

#dNdS_ferret_gene = pivot_wider(dNdS_ferret_gene,names_from = nonsyn, values_from = n)
#dNdS_ferret_gene = select(dNdS_ferret_gene, ferretID,DPI,nonsyn,syn)
#dNdS_ferret_gene$dNdS = paste0(dNdS_ferret_gene$nonsyn / dNdS_ferret_gene$syn)
#dNdS_ferret_gene$dNdS = as.numeric(dNdS_ferret_gene$dNdS)

#dNdS_ferret_gene_plot = ggplot(dNdS_ferret_gene, aes(x = DPI, y = dNdS, color = diet)) +
#  geom_point() +
#  geom_line(aes(group = ferretID)) +
#  facet_grid(segment~diet+inf_route) +
#  PlotTheme1 +
#  DietcolScale
#print(dNdS_ferret_gene_plot)
#ggsave("dNdS_ferret_gene_plot.pdf", dNdS_ferret_gene_plot, path = savedir)
#ggsave("dNdS_ferret_gene_plot.png", dNdS_ferret_gene_plot, path = savedir, height = 10, width = 10)

Do the number of variants correlate with metabolic measures?

SNV location plots

SNVLocation = ggplot(minorvdf, aes(x = ntpos, y = ferretID)) +
  geom_point(aes(color = diet, shape = cohort)) +
  facet_grid(inf_route~segment) +
  PlotTheme1 +
  DietcolScale
print(SNVLocation)
ggsave(SNVLocation, file = "SNVLocation.pdf", path = savedir)
# ferret 1787 doesn't have any variants??

minorvdf$var = paste0(minorvdf$segment,"_",minorvdf$major,minorvdf$ntpos,minorvdf$minor)

# Comparing to SNVs found in the stock

stock = filter(minorvdf, DPI == "Stock")
stock = stock[!duplicated(stock), ]
stocksnv = levels(factor(stock$var))
length(stocksnv)

ferrets = filter(minorvdf, DPI != "Stock")
ferrets = ferrets[!duplicated(ferrets), ]

shared_w_stock = ferrets %>% filter(var %in% stocksnv)
nrow(shared_w_stock)
ferunique = ferrets %>% filter(!(var %in% stocksnv))
nrow(ferunique)
stock_shared = stock[!duplicated(stock$var),] %>% ungroup() 
stock_shared = separate(stock_shared,segment, into = c("strain","CHROM"))
stock_shared$ntvar = paste0(stock_shared$major,stock_shared$ntpos,stock_shared$minor)
stock_shared$aavar = paste0(stock_shared$majoraa,stock_shared$aapos,stock_shared$minoraa)

stock_shared_smol = select(stock_shared,CHROM,ntvar,aavar) %>% droplevels()

SNV Location compared to stock

StockSharedPlot = ggplot(shared_w_stock, aes(x = ntpos, y = ferretID)) +
  geom_point(aes(color = diet, shape = cohort), size = 2) +
  facet_grid(inf_route~segment, drop = FALSE) +
  PlotTheme1 +
  DietcolScale +
  ggtitle("SNVs found in stock")
print(StockSharedPlot)
ggsave(StockSharedPlot, file = "StockSharedPlot.pdf", height = 30, width = 15, path = savedir)

FerUniquePlot = ggplot(ferunique, aes(x = ntpos, y = ferretID)) +
  geom_point(aes(color = diet, shape = cohort)) +
  facet_grid(inf_route~segment) +
  PlotTheme1 +
  DietcolScale +
  ggtitle("SNVs not found in stock")
print(FerUniquePlot)
#ggsave(FerUniquePlot, file = "FerUniquePlot.pdf", path = savedir)

Stock variation

stock_plot = ggplot(filter(shared_w_stock, inf_route != "Aerosol"), 
                    aes(x = DPI, y = minorfreq, color = ferretID)) +
  geom_point() +
  geom_line(aes(group = ferretID)) +
  facet_grid(var~diet+inf_route) +
  PlotTheme1
ggsave("stock_plot.pdf", stock_plot, width = 8, height = 20, path = savedir)

De novo SNVs

denovo = ungroup(ferrets) %>% count(var)

filter(ferrets, var == "H9N2_PB2_A2214C") %>% ungroup() %>% count(ferretID,DPI)
filter(ferrets, var == "H9N2_PB2_A2214C") %>% count(minorfreq)
# found in basically every sample with a freq of 2-5% what is this

Venn diagram of obese and lean de novo SNVs

o_var = filter(ferrets, diet == "Obese") 
o_var = unique(o_var$var)

l_var = filter(ferrets, diet == "Lean") 
l_var = unique(l_var$var)

diet_var <- list(Obese = o_var, Lean = l_var)

#DietUniqueSNVS = ggVennDiagram(diet_var)
#print(DietUniqueSNVS)
#ggsave(DietUniqueSNVS, file = "DietUniqueSNVS.pdf", path = savedir)

Obese- and lean-specific SNVs

lean = ferrets %>% 
  filter(var %in% l_var) %>% 
  filter(!(var %in% o_var)) 

lean$sample_var = paste0(lean$sample,"_",lean$var)
lean = lean[!duplicated(lean$sample_var),] 

lean$ferretID_var = paste0(lean$ferretID,"_",lean$var)
lean = lean[!duplicated(lean$ferretID_var),] 

lean = lean %>% 
  group_by(var) %>% 
  mutate(count = 1, totalsamp = sum(count))

obese = ferrets %>% 
  filter(var %in% o_var) %>% 
  filter(!(var %in% l_var)) 

obese$sample_var = paste0(obese$sample,"_",obese$var)
obese = obese[!duplicated(obese$sample_var),] 

obese$ferretID_var = paste0(obese$ferretID,"_",obese$var)
obese = obese[!duplicated(obese$ferretID_var),] 

obese = obese %>% 
  group_by(var) %>% 
  mutate(count = 1, totalsamp = sum(count))

dietunique = rbind(lean,obese)
dietunique = dietunique[!duplicated(dietunique), ] %>% droplevels()
dietunique = filter(dietunique, inf_route != "Aerosol")
  
DietUnique = ggplot(dietunique, aes(x = ntpos, y = segment)) +
  geom_point(aes(color = nonsyn, size = totalsamp)) + 
  ggtitle("Number of samples containing each variant - diet specific") +
  theme(legend.key = element_blank(),
         strip.background = element_rect(colour="black", fill="white"),
         axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
  facet_grid(diet~STRAIN) +
  PlotTheme1
print(DietUnique)
ggsave(DietUnique, filename = "SegmentSNVPlot_DietUnqique.pdf", path = savedir, width = 10, height = 5)
# make new version of this figure, separating out transmission v independent ferrets
DietUnique_InfRoute = ggplot(dietunique, aes(x = ntpos, y = segment)) +
  geom_point(aes(color = nonsyn, size = totalsamp)) + 
  ggtitle("Number of samples containing each variant - diet specific") +
  theme(legend.key = element_blank(),
         strip.background = element_rect(colour="black", fill="white"),
         axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
  facet_grid(diet~inf_route) +
  PlotTheme1
print(DietUnique_InfRoute)
ggsave(DietUnique_InfRoute, filename = "SegmentSNVPlot_DietUnqique_InfRoute.pdf", 
       path = savedir, width = 15, height = 10)
ggsave(DietUnique_InfRoute, filename = "SegmentSNVPlot_DietUnqique_InfRoute.png", 
       path = savedir, width = 15, height = 10)

dNdS analysis of de novo, diet unique genes

# by ferret
dNdS_denovo_ferret = dietunique %>% 
  ungroup() %>% 
  group_by(ferretID,DPI,diet,inf_route) %>% 
  count(nonsyn)

dNdS_denovo_ferret = pivot_wider(dNdS_denovo_ferret,names_from = nonsyn, values_from = n)
dNdS_denovo_ferret = select(dNdS_denovo_ferret, ferretID,DPI,nonsyn,syn)
dNdS_denovo_ferret$dNdS = paste0(dNdS_denovo_ferret$nonsyn / dNdS_denovo_ferret$syn)
dNdS_denovo_ferret$dNdS = as.numeric(dNdS_denovo_ferret$dNdS)

dNdS_denovo_ferret_plot = ggplot(dNdS_denovo_ferret, aes(x = DPI, y = dNdS, color = ferretID)) +
  geom_point() +
  geom_line(aes(group = ferretID)) +
  facet_grid(~diet+inf_route) +
  PlotTheme1 
print(dNdS_denovo_ferret_plot)
ggsave("dNdS_denovo_ferret.pdf", dNdS_denovo_ferret_plot, path = savedir)
ggsave("dNdS_denovo_ferret.png", dNdS_denovo_ferret_plot, path = savedir, width = 10, height = 5)
# by ferret and gene
dNdS_denovo_ferret_gene = dietunique %>% 
  ungroup() %>% 
  group_by(ferretID,DPI,diet,inf_route,segment) %>% 
  count(nonsyn)

dNdS_denovo_ferret_gene = pivot_wider(dNdS_denovo_ferret_gene,names_from = nonsyn, values_from = n)
dNdS_denovo_ferret_gene = select(dNdS_denovo_ferret_gene, ferretID,DPI,nonsyn,syn)
dNdS_denovo_ferret_gene$dNdS = paste0(dNdS_denovo_ferret_gene$nonsyn / dNdS_denovo_ferret_gene$syn)
dNdS_denovo_ferret_gene$dNdS = as.numeric(dNdS_denovo_ferret_gene$dNdS)

dNdS_denovo_ferret_gene_plot = ggplot(dNdS_denovo_ferret_gene, aes(x = DPI, y = dNdS, color = diet)) +
  geom_point() +
  geom_line(aes(group = ferretID)) +
  facet_grid(segment~diet+inf_route) +
  PlotTheme1 +
  DietcolScale
print(dNdS_denovo_ferret_gene_plot)
ggsave("dNdS_denovo_ferret_gene_plot.pdf", dNdS_denovo_ferret_gene_plot, path = savedir)
ggsave("dNdS_denovo_ferret_gene_plot.png", dNdS_denovo_ferret_gene_plot, path = savedir)
#ggplot(filter(dietunique, totalsamp > 1), aes(x = DPI, y = minorfreq, color = nonsyn)) +
#  geom_point() +
#  geom_line(aes(group = var)) +
#  facet_grid(ferretID~diet+inf_route) +
#  PlotTheme1 
nonsyns = filter(dietunique, nonsyn == "nonsyn" & totalsamp > 1) %>% ungroup() %>% droplevels()
nonsyns = nonsyns[!duplicated(nonsyns$var),] 

nonsyns = separate(nonsyns,segment, into = c("strain","CHROM"))
nonsyns$ntvar = paste0(nonsyns$major,nonsyns$ntpos,nonsyns$minor)
nonsyns$aavar = paste0(nonsyns$majoraa,nonsyns$aapos,nonsyns$minoraa)

nonsyns_smol = select(nonsyns,CHROM,ntvar,aavar,diet,totalsamp) %>% droplevels()
write.csv(nonsyns_smol, "nonsyns.csv")

Which ferrets have more than one de novo?

ggplot(dietunique, aes(x = ntpos, y = ferretID)) +
  geom_point(aes(color = diet)) +
  facet_grid(~segment) +
  PlotTheme1 +
  DietcolScale

ggplot(filter(dietunique, totalsamp >1), aes(x = ntpos, y = ferretID)) +
  geom_point(aes(color = diet)) +
  facet_grid(~segment) +
  PlotTheme1 +
  DietcolScale

AF of shared de novos

ggplot(filter(dietunique, totalsamp >1), aes(x = DPI, y = minorfreq)) +
  geom_point(aes(color = var)) +
  facet_grid(~ferretID) +
  PlotTheme1

SNVs shared between diet groups

shared = ferrets %>% 
  filter(var %in% o_var) %>% 
  filter(var %in% l_var) %>% 
  group_by(var) %>% 
  mutate(count = 1, totalsamp = sum(count))

SharedPlot = ggplot(shared, aes(x = ntpos, y = segment)) +
  geom_point(aes(size = totalsamp, color = nonsyn)) +
  ggtitle("Number of samples containing each variant - Shared between diet groups") +
  theme(legend.key = element_blank(),
         strip.background = element_rect(colour="black", fill="white"),
         axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
  PlotTheme1
print(SharedPlot)
ggsave(SharedPlot, filename = "SegmentSNVPlot_DietShared.pdf", path = savedir)
Minorfreq_dist = ggplot(ferrets, aes(x = minorfreq, fill = diet)) +
  geom_histogram(binwidth = 0.01) +
  PlotTheme1 +
  facet_grid(inf_route~diet) +
  DietcolScale_fill
print(Minorfreq_dist)
ggsave("Minorfreq_dist.pdf", Minorfreq_dist, path = savedir)
# obese seem to have fewer low-frequency de novo SNVs
obese_index = filter(ferrets, diet == "Obese" & inf_route == "Index") %>% ungroup()
lean_index = filter(ferrets, diet == "Lean" & inf_route == "Index") %>% ungroup()
t.test(obese_index$minorfreq, lean_index$minorfreq)
# means are not different

obese_contact = filter(ferrets, diet == "Obese" & inf_route == "Contact") %>% ungroup()
lean_contact = filter(ferrets, diet == "Lean" & inf_route == "Contact") %>% ungroup()
t.test(obese_contact$minorfreq, lean_contact$minorfreq)
# means are not different

# QQ_Plot: compares the quantiles of two distributions, x =y suggests they are drawn from the same distribution
qqnorm(obese_index$minorfreq, main = "Obese Index - Test of Normal Distribution")
qqnorm(lean_index$minorfreq, main = "Lean Index - Test of Normal Distribution")
# neither distribution is normal
qqplot(obese_index$minorfreq,lean_index$minorfreq, xlab = "Obese Index", ylab = "Lean Index")

qqnorm(obese_contact$minorfreq, main = "Obese Contact - Test of Normal Distribution")
qqnorm(lean_contact$minorfreq, main = "Lean Contact - Test of Normal Distribution")
# neither distribution is normal
qqplot(obese_contact$minorfreq,lean_contact$minorfreq, xlab = "Obese Contact", ylab = "Lean Contact")

# Mann-Whitney-Wilcox test (Mann-Whitney U test): samples are not normally distributed and independent of each other
wilcox.test(obese_index$minorfreq,lean_index$minorfreq)
wilcox.test(obese_contact$minorfreq,lean_contact$minorfreq)
# distributions are not different

# Kolmogorov-Smirnov test: samples are not normally distributed and independent of each other
# "sensitive to differences in location and shape of the empirical CDFs of the two samples"
ks.test(obese_index$minorfreq,lean_index$minorfreq)
ks.test(obese_contact$minorfreq,lean_contact$minorfreq)
# distributions are not different
highfreq = filter(ferrets, minorfreq > 0.25)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpNZXJnaW5nIHRyYW5zbWlzc2lvbiBwYWlyIGRhdGEgZ2V0cyByaWQgb2YgYWxsIG9mIFcxNyBmZXJyZXRzIC0gYXZvaWQgdGhpcwoKYGBge3J9CmxpYnJhcnkoInRpZHlyIikKbGlicmFyeSgnZ2dwbG90MicpCmxpYnJhcnkoJ2RwbHlyJykKbGlicmFyeSgiZ2dWZW5uRGlhZ3JhbSIpCmxpYnJhcnkoImdsdWUiKQoKd2tkaXIgPSAifi9EZXNrdG9wL0dpdEh1Yi9PYmVzaXR5L05ld0V4dHJhY3Rpb25zL0g5TjIiCnNldHdkKHdrZGlyKQpzYXZlZGlyID0gIn4vRGVza3RvcC9HaXRIdWIvT2Jlc2l0eS9OZXdFeHRyYWN0aW9ucy9IOU4yL091dHB1dF9GaWd1cmVzIgoKc291cmNlKCJ+L0Rlc2t0b3AvR2l0SHViL09iZXNpdHkvTmV3RXh0cmFjdGlvbnMvSDlOMi9GRF9mdW5jdGlvbnMuUiIpCmBgYAoKYGBge3J9CmRpZXQgPSBjKCJPYmVzZSIsIkxlYW4iLCJDb250cm9sIikKZGlldENvbG9ycyA9IGMoIiNGRjk5MzMiLCIjNjZDQ0ZGIiwiIzYwNjA2MCIpCm5hbWVzKGRpZXRDb2xvcnMpID0gZGlldApEaWV0Y29sU2NhbGVfZmlsbCA8LSBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gImdycCIsdmFsdWVzID0gZGlldENvbG9ycykKRGlldGNvbFNjYWxlIDwtIHNjYWxlX2NvbG91cl9tYW51YWwobmFtZSA9ICJncnAiLHZhbHVlcyA9IGRpZXRDb2xvcnMpCmBgYAoKI0xvYWRpbmcgbWV0YWRhdGEKVGhpcyBpbmNsdWRlcyB0aXRlciBhbmQgQ3QgdmFsdWVzIHdoZW4gYXBwbGljYWJsZS4gTkQgaW5kaWNhdGVzIHFQQ1Igd2FzIHJ1biB3aXRoIGEgbmVnYXRpdmUgcmVzdWx0OyAwIGluZGljYXRlcyBwbGFxdWUgYXNzYXkgb3IgSEFJIHdhcyBydW4gd2l0aCBhIG5lZ2F0aXZlIHJlc3VsdC4gTkEgZm9yIGFueSB2YWx1ZXMgaW5kaWNhdGUgdGhhdCBkYXRhIHdhcyBtaXNzaW5nLiBTYWNyaWZpY2VkIGluZGljYXRlcyB0aGVyZSB3YXMgbm8gZGF0YSBhdCB0aGF0IHRpbWUgcG9pbnQgYmVjYXVzZSB0aGUgZmVycmV0IGhhZCBhbHJlYWR5IGJlZW4gc2FjcmZpY2llZCBmb3IgcGF0aG9sb2d5LiAKYGBge3J9Cm1ldGFmaWxlID0gIkg5X01ldGFkYXRhLmNzdiIKCm1ldGEgPSByZWFkLmNzdihmaWxlPW1ldGFmaWxlLGhlYWRlcj1ULHNlcD0iLCIsbmEuc3RyaW5ncyA9IGMoJycpKQptZXRhID0gZmlsdGVyKG1ldGEsIHJlc2VxdWVuY2VkID09ICJ5ZXMiKQoKbWV0YSRDdF9NZ2VuZSA9IGFzLm51bWVyaWMobWV0YSRDdF9NZ2VuZSkKbWV0YSR0aXRlciA9IGFzLm51bWVyaWMobWV0YSR0aXRlcikKbWV0YSRsb2cxMF90aXRlciA9IGFzLm51bWVyaWMobWV0YSRsb2cxMF90aXRlcikKCm1ldGEkaW5mX3JvdXRlID0gZmFjdG9yKG1ldGEkaW5mX3JvdXRlLCBsZXZlbHMgPSBjKCJJbmRleCIsIkNvbnRhY3QiLCJBZXJvc29sIiwiQ29udHJvbCIpKQpgYGAKCiMgUHJlIFNlcXVlbmNlIEFuYWx5c2lzCgpDdCAmIFRpdGVyIEFuYWx5c2lzCmBgYHtyfQptZXRhJGluZl9yb3V0ZSA9IGZhY3RvcihtZXRhJGluZl9yb3V0ZSwgbGV2ZWxzID0gYygiSW5kZXgiLCJDb250YWN0IiwiQWVyb3NvbCIsIkNvbnRyb2wiKSkKCkNUX3Bsb3QgPSBnZ3Bsb3QoZmlsdGVyKG1ldGEsIGluZl9yb3V0ZSA9PSAiSW5kZXgiIHwgaW5mX3JvdXRlID09ICJDb250YWN0IiksIAogICAgICAgYWVzKHggPSBEUEksIHkgPSBDdF9NZ2VuZSwgY29sb3IgPSBhcy5jaGFyYWN0ZXIoZmVycmV0SUQpKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gZmVycmV0SUQpLCBzaXplID0gMS41KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMzAsIGxpbmV0eXBlID0gImRvdHRlZCIpICsKICBmYWNldF9ncmlkKGRpZXR+aW5mX3JvdXRlKSArCiAgUGxvdFRoZW1lMQpwcmludChDVF9wbG90KQpnZ3NhdmUoIkNUX3Bsb3QucG5nIixDVF9wbG90LCBwYXRoID0gc2F2ZWRpciwgd2lkdGggPSAxNSwgaGVpZ2h0ID0gNykKClRpdGVyc19wbG90ID0gZ2dwbG90KGZpbHRlcihtZXRhLCBpbmZfcm91dGUgPT0gIkluZGV4IiB8IGluZl9yb3V0ZSA9PSAiQ29udGFjdCIpLCAKICAgICAgIGFlcyh4ID0gRFBJLCB5ID0gbG9nMTBfdGl0ZXIsIGNvbG9yID0gYXMuY2hhcmFjdGVyKGZlcnJldElEKSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGZlcnJldElEKSwgc2l6ZSA9IDEuNSkgKwogIHlsaW0oMCw3KSArCiAgZmFjZXRfZ3JpZChkaWV0fmluZl9yb3V0ZSkgKwogIFBsb3RUaGVtZTEKcHJpbnQoVGl0ZXJzX3Bsb3QpCmdnc2F2ZSgiVGl0ZXJzX3Bsb3QucG5nIixUaXRlcnNfcGxvdCwgcGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gMTUsIGhlaWdodCA9IDcpCmBgYAoKIyBTZXF1ZW5jaW5nIEFuYWx5c2lzCgpTcGVjaWZ5aW5nIHRocmVzaG9sZHMgYW5kIHBsb3R0aW5nIHZhcmlhYmxlcwpgYGB7cn0KY292X2N1dCA9IDIwMApmcmVxX2N1dCA9IDAuMDEKcHZhbGN1dCAgPSAwLjA1CgpudGxpc3QgPSBjKCJBIiwiQyIsIkciLCJUIikKU0VHTUVOVFMgPSBjKCdIOU4yX1BCMicsJ0g5TjJfUEIxJywnSDlOMl9QQScsJ0g5TjJfSEEnLCdIOU4yX05QJywnSDlOMl9OQScsJ0g5TjJfTVAnLCdIOU4yX05TJykKYGBgCgpMb2FkaW5nIGluIGNvdmVyYWdlIGZpbGUgJiBzZWdtZW50IHNpemUgaW5mb3JtYXRpb24KYGBge3J9CmNvdiA9IHJlYWQuY3N2KCIuL2F2Z19jb3ZlcmFnZS9IOU4yLmNvdmVyYWdlLmNzdiIsIGhlYWRlciA9IFRSVUUsIHNlcCA9ICIsIikKCnNlZ19zaXplcyA9ICJTZWdtZW50U2l6ZS5jc3YiCnNpemVzID0gcmVhZC5jc3YoZmlsZT1zZWdfc2l6ZXMsaGVhZGVyPVQsc2VwPSIsIixuYS5zdHJpbmdzID0gYygnJykpCkdlbm9tZVNpemUgPSAoc2l6ZXMgJT4lIGZpbHRlcihzZWdtZW50ID09ICdIOU4yX0dFTk9NRScpKSRTZWdtZW50U2l6ZQoKY292JHNlZ21lbnQgPSBmYWN0b3IoY292JHNlZ21lbnQsIGxldmVscyA9IFNFR01FTlRTKQpgYGAKCkNoZWNraW5nIGlmIGRhdGEgcGFzc2VzIHRocmVzaG9sZHMgJiBtYWtlIGNvdmVyYWdlIHBsb3RzCmBgYHtyfQpjb3ZfY2hlY2sgPSBDb3ZlcmFnZUFjcm9zcyhjb3YsY292X2N1dCw3MCxzaXplcywgd2tkaXIpCmBgYAoKYGBge3J9CmNvdl9xdWFsID0gc2VsZWN0KGNvdl9jaGVjaywgbmFtZSwgcXVhbGl0eSkKY292X2F2Z3RpdGVyID0gbWVyZ2UoY292LCBjb3ZfcXVhbCwgYnkgPSBjKCJuYW1lIikpCgpjb3ZfYXZndGl0ZXIkdG90YWxjb3VudFtpcy5uYShjb3ZfYXZndGl0ZXIkdG90YWxjb3VudCldID0gMApjb3ZfYXZndCA9IGdyb3VwX2J5KGNvdl9hdmd0aXRlcixzZWdtZW50LG50cG9zLHF1YWxpdHkpICU+JQogIG11dGF0ZShhdmdfY292ID0gbWVhbih0b3RhbGNvdW50KSkKCmF2Z190aXRlcl9wbG90ID0gZ2dwbG90KGNvdl9hdmd0LCBhZXMoeCA9IG50cG9zLCB5ID0gYXZnX2NvdiwgY29sb3IgPSBxdWFsaXR5KSkgKwogIGdlb21fbGluZSgpICsKICBmYWNldF9ncmlkKH5zZWdtZW50KSArCiAgUGxvdFRoZW1lMQpwcmludChhdmdfdGl0ZXJfcGxvdCkKZ2dzYXZlKCJhdmdfdGl0ZXJfcGxvdC5wZGYiLGF2Z190aXRlcl9wbG90LHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQpgYGAKCk1lcmdpbmcgY292ZXJhZ2UgY2hlY2sgaW5mbyB3aXRoIHRoZSByZXN0IG9mIHRoZSBtZXRhZGF0YQpgYGB7cn0KbWV0YSA9IG1lcmdlKG1ldGEsIGNvdl9jaGVjaywgYnkueCA9IGMoInNhbXBsZSIpLCBieS55ID0gYygibmFtZSIpLCBhbGwueSA9IFRSVUUpCgpucm93KG1ldGEpCmNvdW50KG1ldGEscXVhbGl0eSkKYGBgCgojIE1ha2luZyB0aXRlciBwbG90cwpgYGB7cn0KZ2dwbG90KGZpbHRlcihtZXRhLCBEUEkgPT0gImQwMiIgfCBEUEkgPT0gImQwNCIgfCBEUEkgPT0gImQwNiIgfAogICAgICAgICAgICAgICAgRFBJID09ICJkMDgiIHxEUEkgPT0gImQxMCIgfCBEUEkgPT0gImQxMiIpLAogICAgICAgYWVzKHggPSBEUEksIHkgPSBsb2cxMF90aXRlciwgY29sb3IgPSBkaWV0KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGZlcnJldElEKSkgKwogIGZhY2V0X2dyaWQofmluZl9yb3V0ZSkgKwogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQoKIyBkb24ndCBoYXZlIHRpdGVyIGluZm9ybWF0aW9uIGZvciBXMTcgY29ob3J0IChwcm9iYWJseSB3ZXJlIG5ldmVyIG1lYXN1cmVkKQojIGRvbid0IGhhdmUgdGhpcyBpbmZvIHBhc3QgZGF5IDYgZm9yIHNvbWUgZmVycmV0cyBzYWNyaWZpY2VkIGZvciBwYXRob2xvZ3kgYXQgU3QgSnVkZSdzCgptMSA9IGZpbHRlcihtZXRhLCB0aXRlciAhPSAiTkEiICYgdGl0ZXIgIT0gInNhY3JpZmljZWQiKSAlPiUKICBmaWx0ZXIoRFBJID09ICJkMDIiIHwgRFBJID09ICJkMDQiIHwgRFBJID09ICJkMDYiIHwKICAgICAgICAgICAgICAgIERQSSA9PSAiZDA4IiB8IERQSSA9PSAiZDEwIiB8IERQSSA9PSAiZDEyIikgJT4lCiAgZ3JvdXBfYnkoaW5mX3JvdXRlLCBkaWV0LCBEUEksY29ob3J0KSAlPiUKICBtdXRhdGUoYXZnX3RpdGVyID0gbWVhbih0aXRlcikpICU+JQogIG11dGF0ZShhdmdfbG9nX3RpdGVyID0gbWVhbihsb2cxMF90aXRlcikpICU+JQogIHVuZ3JvdXAoKQoKYXZnX3RpdGVyID0gZ2dwbG90KGZpbHRlcihtMSwgaW5mX3JvdXRlID09ICJJbmRleCIgfCBpbmZfcm91dGUgPT0gIkNvbnRhY3QiKSwgCiAgICAgICAgICAgICAgYWVzKHggPSBEUEksIHkgPSBhdmdfbG9nX3RpdGVyLCBjb2xvciA9IGNvaG9ydCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGNvaG9ydCksIHNpemUgPSAxLjUpICsKICBmYWNldF9ncmlkKGRpZXR+aW5mX3JvdXRlKSArCiAgeWxpbSgwLDYpICsgCiAgUGxvdFRoZW1lMSAjKwojICBEaWV0Y29sU2NhbGUKcHJpbnQoYXZnX3RpdGVyKQpnZ3NhdmUoImF2Z190aXRlci5wZGYiLCBhdmdfdGl0ZXIsIHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQoKbTFfZ29vZCA9IGZpbHRlcihtZXRhLCBxdWFsaXR5ID09ICJnb29kIikgJT4lIAogIGZpbHRlcih0aXRlciAhPSAiTkEiICYgdGl0ZXIgIT0gInNhY3JpZmljZWQiKSAlPiUKICBmaWx0ZXIoRFBJID09ICJkMDIiIHwgRFBJID09ICJkMDQiIHwgRFBJID09ICJkMDYiIHwKICAgICAgICAgICAgICAgIERQSSA9PSAiZDA4IiB8IERQSSA9PSAiZDEwIiB8IERQSSA9PSAiZDEyIikgJT4lCiAgZ3JvdXBfYnkoaW5mX3JvdXRlLCBkaWV0LCBEUEkpICU+JQogIG11dGF0ZShhdmdfdGl0ZXIgPSBtZWFuKHRpdGVyKSkgJT4lCiAgbXV0YXRlKGF2Z19sb2dfdGl0ZXIgPSBtZWFuKGxvZzEwX3RpdGVyKSkgJT4lCiAgdW5ncm91cCgpCgphdmdfdGl0ZXJfbm96ZXJvZXMgPSBnZ3Bsb3QoZmlsdGVyKG0xX2dvb2QsaW5mX3JvdXRlID09ICJJbmRleCIgfCBpbmZfcm91dGUgPT0gIkNvbnRhY3QiKSwgCiAgICAgICAgICAgICAgYWVzKHggPSBEUEksIHkgPSBhdmdfbG9nX3RpdGVyLCBjb2xvciA9IGRpZXQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMykgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBkaWV0KSwgc2l6ZSA9IDEuNSkgKwogIGZhY2V0X2dyaWQofmluZl9yb3V0ZSkgKwogIHlsaW0oMCw2KSArIAogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQpwcmludChhdmdfdGl0ZXJfbm96ZXJvZXMpCmdnc2F2ZSgiYXZnX3RpdGVyX25vemVyb2VzLnBkZiIsYXZnX3RpdGVyX25vemVyb2VzLHBhdGggPSBzYXZlZGlyLHdpZHRoID0gNywgaGVpZ2h0ID0gNSkKCm0xX2FsbCA9IGZpbHRlcihtZXRhLCB0aXRlciAhPSAiTkEiICYgdGl0ZXIgIT0gInNhY3JpZmljZWQiKSAlPiUKICBmaWx0ZXIoRFBJID09ICJkMDIiIHwgRFBJID09ICJkMDQiIHwgRFBJID09ICJkMDYiIHwKICAgICAgICAgICAgICAgIERQSSA9PSAiZDA4IiB8IERQSSA9PSAiZDEwIiB8IERQSSA9PSAiZDEyIikgJT4lCiAgZ3JvdXBfYnkoZGlldCwgRFBJKSAlPiUKICBtdXRhdGUoYXZnX3RpdGVyID0gbWVhbih0aXRlcikpICU+JQogIG11dGF0ZShhdmdfbG9nX3RpdGVyID0gbWVhbihsb2cxMF90aXRlcikpICU+JQogIHVuZ3JvdXAoKQoKYXZnX3RpdGVyX2FsbCA9IGdncGxvdChmaWx0ZXIobTFfYWxsLGluZl9yb3V0ZSA9PSAiSW5kZXgiIHwgaW5mX3JvdXRlID09ICJDb250YWN0IiksIAogICAgICAgICAgICAgIGFlcyh4ID0gRFBJLCB5ID0gYXZnX2xvZ190aXRlciwgY29sb3IgPSBkaWV0KSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gZGlldCksIHNpemUgPSAxLjUpICsKICB5bGltKDAsNikgKyAKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKcHJpbnQoYXZnX3RpdGVyX2FsbCkKCm0xX2FsbF9nb29kID0gZmlsdGVyKG1ldGEsIHF1YWxpdHkgPT0gImdvb2QiKSAlPiUgCiAgZmlsdGVyKHRpdGVyICE9ICJOQSIgJiB0aXRlciAhPSAic2FjcmlmaWNlZCIpICU+JQogIGZpbHRlcihEUEkgPT0gImQwMiIgfCBEUEkgPT0gImQwNCIgfCBEUEkgPT0gImQwNiIgfAogICAgICAgICAgICAgICAgRFBJID09ICJkMDgiIHwgRFBJID09ICJkMTAiIHwgRFBJID09ICJkMTIiKSAlPiUKICBncm91cF9ieShkaWV0LCBEUEkpICU+JQogIG11dGF0ZShhdmdfdGl0ZXIgPSBtZWFuKHRpdGVyKSkgJT4lCiAgbXV0YXRlKGF2Z19sb2dfdGl0ZXIgPSBtZWFuKGxvZzEwX3RpdGVyKSkgJT4lCiAgdW5ncm91cCgpCgphdmdfdGl0ZXJfYWxsX2dvb2Q9IGdncGxvdChmaWx0ZXIobTFfYWxsX2dvb2QsaW5mX3JvdXRlID09ICJJbmRleCIgfCBpbmZfcm91dGUgPT0gIkNvbnRhY3QiKSwgCiAgICAgICAgICAgICAgYWVzKHggPSBEUEksIHkgPSBhdmdfbG9nX3RpdGVyLCBjb2xvciA9IGRpZXQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMykgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBkaWV0KSwgc2l6ZSA9IDEuNSkgKwogIHlsaW0oMCw2KSArIAogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQpwcmludChhdmdfdGl0ZXJfYWxsX2dvb2QpCmBgYAoKYGBge3J9CmdncGxvdChmaWx0ZXIobTEsIERQSSA9PSAiZDAyIiB8IERQSSA9PSAiZDA0IiB8IERQSSA9PSAiZDA2IiB8CiAgICAgICAgICAgICAgICBEUEkgPT0gImQwOCIgfCBEUEkgPT0gImQxMCIgfCBEUEkgPT0gImQxMiIpLAogICAgICAgYWVzKHggPSBEUEksIHkgPSBDdF9NZ2VuZSkpICsKICBnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0KZ2dwbG90KGZpbHRlcihtMSwgRFBJID09ICJkMDIiIHwgRFBJID09ICJkMDQiIHwgRFBJID09ICJkMDYiIHwKICAgICAgICAgICAgICAgIERQSSA9PSAiZDA4IiB8IERQSSA9PSAiZDEwIiB8IERQSSA9PSAiZDEyIiksCiAgICAgICBhZXMoeCA9IGxvZzEwX3RpdGVyLCB5ID0gQ3RfTWdlbmUpKSArCiAgZ2VvbV9wb2ludCgpICsKICB4bGltKDAsOCkgKwogIFBsb3RUaGVtZTEKCmdncGxvdChmaWx0ZXIobTEsIGxvZzEwX3RpdGVyID4gMSksIGFlcyh4ID0gbG9nMTBfdGl0ZXIsIHkgPSBDdF9NZ2VuZSkpICsKICBnZW9tX3BvaW50KCkgKwogIHhsaW0oMCw4KSArCiAgUGxvdFRoZW1lMQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWV0YSwgYWVzKHggPSBxdWFsaXR5LCB5ID0gbG9nMTBfdGl0ZXIpKSArCiAgZ2VvbV9wb2ludCgpCmBgYAoKYGBge3J9CmdncGxvdChtZXRhLCBhZXMoeCA9IHF1YWxpdHksIHkgPSBDdF9NZ2VuZSkpICsKICBnZW9tX3BvaW50KCkKCkN0X2Rpc3RfcGxvdCA9IGdncGxvdChtZXRhLCBhZXMoeCA9IEN0X01nZW5lLCBmaWxsID0gcXVhbGl0eSkpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAzMiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIFBsb3RUaGVtZTEgKwogIHlsYWIoIk51bWJlciBvZiBzYW1wbGVzIikKcHJpbnQoQ3RfZGlzdF9wbG90KQpnZ3NhdmUoIkN0X2Rpc3RfcGxvdC5wZGYiLEN0X2Rpc3RfcGxvdCxwYXRoID0gc2F2ZWRpciwgd2lkdGggPSA3LCBoZWlnaHQgPSA1KQpgYGAKClVzaW5nIEN0X01nZW5lID0gMzIgYXMgMVggZ2Vub21lIGNvcHkgY3V0b2ZmCmBgYHtyfQptZXRhX0N0MSA9IGZpbHRlcihtZXRhLCBDdF9NZ2VuZSA8IDMyKSAlPiUKICBkcm9wbGV2ZWxzKCkKbWV0YV9DdDIgPSBmaWx0ZXIobWV0YSwgQ3RfTWdlbmUgPiAzMikgJT4lCiAgZHJvcGxldmVscygpCm1ldGFfQ3QyJEN0X01nZW5lID0gMzIKCm1ldGFfQ3QgPSByYmluZChtZXRhX0N0MSwgbWV0YV9DdDIpCmBgYAoKQWRkaW5nIGdlbm9tZSBjb3B5IG51bWJlciBpbmZvCmBgYHtyfQpDdDMyID0gZmlsdGVyKG1ldGFfQ3QsIEN0X01nZW5lID09IDMyKQpDdDMyJGdlbm9tZWNvcHkgPSAxCgpDdDMxID0gZmlsdGVyKG1ldGFfQ3QsIEN0X01nZW5lIDw9IDMyICYgQ3RfTWdlbmUgPiAzMSkKQ3QzMSRnZW5vbWVjb3B5ID0gMgoKQ3QzMCA9IGZpbHRlcihtZXRhX0N0LCBDdF9NZ2VuZSA8PSAzMSAmIEN0X01nZW5lID4gMzApCkN0MzAkZ2Vub21lY29weSA9IDQKCkN0MjkgPSBmaWx0ZXIobWV0YV9DdCwgQ3RfTWdlbmUgPD0gMzAgJiBDdF9NZ2VuZSA+IDI5KQpDdDI5JGdlbm9tZWNvcHkgPSA4CgpDdDI4ID0gZmlsdGVyKG1ldGFfQ3QsIEN0X01nZW5lIDw9IDI5ICYgQ3RfTWdlbmUgPiAyOCkKQ3QyOCRnZW5vbWVjb3B5ID0gMTYKCkN0MjcgPSBmaWx0ZXIobWV0YV9DdCwgQ3RfTWdlbmUgPD0gMjggJiBDdF9NZ2VuZSA+IDI3KQpDdDI3JGdlbm9tZWNvcHkgPSAzMgoKQ3QyNiA9IGZpbHRlcihtZXRhX0N0LCBDdF9NZ2VuZSA8PSAyNyAmIEN0X01nZW5lID4gMjYpCkN0MjYkZ2Vub21lY29weSA9IDY0CgpDdDI1ID0gZmlsdGVyKG1ldGFfQ3QsIEN0X01nZW5lIDw9IDI2ICYgQ3RfTWdlbmUgPiAyNSkKQ3QyNSRnZW5vbWVjb3B5ID0gMTI4CgpDdDI0ID0gZmlsdGVyKG1ldGFfQ3QsIEN0X01nZW5lIDw9IDI1ICYgQ3RfTWdlbmUgPiAyNCkKQ3QyNCRnZW5vbWVjb3B5ID0gMjU2CgpDdDIzID0gZmlsdGVyKG1ldGFfQ3QsIEN0X01nZW5lIDw9IDI0ICYgQ3RfTWdlbmUgPiAyMykKQ3QyMyRnZW5vbWVjb3B5ID0gNTEyCgpDdDIyID0gZmlsdGVyKG1ldGFfQ3QsIEN0X01nZW5lIDw9IDIzICYgQ3RfTWdlbmUgPiAyMikKQ3QyMiRnZW5vbWVjb3B5ID0gMTAyNAoKQ3QyMSA9IGZpbHRlcihtZXRhX0N0LCBDdF9NZ2VuZSA8PSAyMiAmIEN0X01nZW5lID4gMjEpCkN0MjEkZ2Vub21lY29weSA9IDIwNDgKYGBgCgpgYGB7cn0KbWV0YV9DdCA9IHJiaW5kKEN0MzIsQ3QzMSxDdDMwLEN0MjksQ3QyOCxDdDI3LEN0MjYsQ3QyNSxDdDI0LEN0MjMsQ3QyMixDdDIxKQpgYGAKCmBgYHtyfQpnZ3Bsb3QobWV0YV9DdCwgYWVzKHggPSBDdF9NZ2VuZSwgeSA9IGdlbm9tZWNvcHkpKSArCiAgZ2VvbV9wb2ludCgpICsKICBQbG90VGhlbWUxCmBgYAoKYGBge3J9CmdncGxvdChtZXRhX0N0LCBhZXMoeCA9IGxvZzEwX3RpdGVyLCB5ID0gZ2Vub21lY29weSkpICsKICBnZW9tX3BvaW50KCkKYGBgCgpMb2FkaW5nIGluIHZhcmlhbnQgZmlsZXMKYGBge3J9CnZhcmZpbGUgPSAiLi92YXJmaWxlcy9IOU4yLlZhcmlhbnRzT25seS4wLjAxLjIwMC5jc3YiCgojIHJlYWQgYW5kIHJlYXJyYW5nZSB0aGUgZGF0YQp2YXJzID0gcmVhZC5jc3YoZmlsZT12YXJmaWxlLGhlYWRlcj1ULHNlcD0iLCIsbmEuc3RyaW5ncyA9IGMoJycpKQp2YXJzJG5hbWUgPSB2YXJzJHNhbXBsZQpgYGAKClJlYXJyYW5naW5nIHZhcmlhbnQgZGF0YWZyYW1lCmBgYHtyfQp2ZGYgPSBBcnJhbmdlVmFyV1JlcCh2YXJzKQojIGFscmVhZHkgaGF2ZSByZXBsaWNhdGUgZGF0YSBpbiB0aGUgdmFyZmlsZXMgZnJvbSBydW5uaW5nIENvbXBhcmVSZXBzLnYyLnB5IHNjcmlwdAp2ZGYgPSB2ZGZbIWR1cGxpY2F0ZWQodmRmKSwgXSAlPiUgZHJvcGxldmVscygpCm5yb3codmRmKQpgYGAKCkZpbHRlcmluZyB2YXJpYW50IGRmIGJ5IHRpbW8gYmlub2NoZWNrCmBgYHtyfQp2ZGYkYmlub2NoZWNrID0gZmFjdG9yKHZkZiRiaW5vY2hlY2ssIGxldmVscyA9IGMoIkZhbHNlIiwiUjEiLCJSMiIsIlRydWUiKSkKdmRmX2Jpbm8gPSBmaWx0ZXIodmRmLCBiaW5vY2hlY2sgIT0gIkZhbHNlIikKdmRmX2Jpbm8gPSB2ZGZfYmlub1shZHVwbGljYXRlZCh2ZGZfYmlubyksIF0gJT4lIGRyb3BsZXZlbHMoKQpucm93KHZkZl9iaW5vKQojIHRoaXMgcmVhbGx5IGdldHMgcmlkIG9mIGEgbG90IG9mIHZhcmlhbnRzICh+MTAwMCkKCnZkZl9ub2Jpbm8gPSBmaWx0ZXIodmRmLCBiaW5vY2hlY2sgIT0gIlRydWUiKQp2ZGZfbm9iaW5vID0gdmRmX25vYmlub1shZHVwbGljYXRlZCh2ZGZfbm9iaW5vKSwgXSAlPiUgZHJvcGxldmVscygpCm5yb3codmRmX25vYmlubykKCnJhbmdlKHZkZl9ub2Jpbm8kbWlub3JmcmVxKQpnZ3Bsb3QodmRmX25vYmlubywgYWVzKHggPSBtaW5vcmZyZXEpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAxKSArCiAgUGxvdFRoZW1lMQpgYGAKCkZpbHRlcmluZyB2YXJpYW50IGRmIHdpdGggZnJlcXVlbmN5IGN1dG9mZnMKYGBge3J9CnZkZiA9IGZpbHRlcih2ZGYsIG1pbm9yZnJlcTEgPj0gZnJlcV9jdXQgJiAKICAgICAgICAgICAgICAgbWlub3JmcmVxMiA+PSBmcmVxX2N1dCAmIAogICAgICAgICAgICAgICBtaW5vciAlaW4lIG50bGlzdCAmCiAgICAgICAgICAgICAgIG1ham9yICVpbiUgbnRsaXN0KSAlPiUgCiAgICAgICAgICAgIGRyb3BsZXZlbHMoKQojIGJhc2VkIG9uIE1BRiBzdHVkeSwgcmVwcyBhbmQgMC4wMSUgY3V0b2ZmIHdhcyBiZXN0IGNvbWJvCiNmaWx0ZXIgZWFjaCByZXBsaWNhdGUgc2VwYXJhdGVseSByYXRoZXIgdGhhbiB1c2luZyB0aGUgYXZlcmFnZQoKdmRmID0gdmRmWyFkdXBsaWNhdGVkKHZkZiksIF0gJT4lIGRyb3BsZXZlbHMoKQpucm93KHZkZikKIyBkb2VzIG5vdCBlbGltaW5hdGUgYW55IHZhcmlhbnRzIGhlcmUKYGBgCgpBZGRpbmcgbWV0YWRhdGEKYGBge3J9CnZkZiA9IG1lcmdlKHZkZixtZXRhLCBieSA9IGMoInNhbXBsZSIsInNlZ21lbnQiKSkKdmRmID0gdmRmWyFkdXBsaWNhdGVkKHZkZiksIF0gJT4lIGRyb3BsZXZlbHMoKQoKdmRmJHNlZ21lbnQgPSBmYWN0b3IodmRmJHNlZ21lbnQsIGxldmVscyA9IFNFR01FTlRTKQoKdmRmID0gZmlsdGVyKHZkZiwgaW5mX3JvdXRlID09ICJJbmRleCIgfCBpbmZfcm91dGUgPT0gIkNvbnRhY3QiIHwgaW5mX3JvdXRlID09ICJDb250cm9sIikKIyBpZ25vcmluZyBhZXJvc29sIGZvciBub3cKYGBgCgpgYGB7cn0KdmRmID0gZmlsdGVyKHZkZiwgcXVhbGl0eSA9PSAiZ29vZCIpCnZkZiA9IHZkZlshZHVwbGljYXRlZCh2ZGYpLCBdICU+JSBkcm9wbGV2ZWxzKCkKCmdvb2RfbmFtZXMgPSBjKGxldmVscyhmYWN0b3IodmRmJHNhbXBsZSkpKQpgYGAKCgpTTlZzIGNvcnJlbGF0ZWQgdG8gdGl0ZXI/CmBgYHtyfQp2ZGZfY291bnQgPSBncm91cF9ieSh2ZGYsIHNhbXBsZSwgY29ob3J0LCBmZXJyZXRJRCxEUEksIGluZl9yb3V0ZSwgZGlldCwgU1RSQUlOLCByZXNlcXVlbmNlZCwgcXVhbGl0eSkgJT4lCiAgdGFsbHkoKQp0aXRlciA9IHNlbGVjdChtZXRhLCBzYW1wbGUsIHRpdGVyKQoKdmRmX2NvdW50X3RpdGVyID0gbWVyZ2UodmRmX2NvdW50LHRpdGVyLCBieSA9IGMoInNhbXBsZSIpKQp2ZGZfY291bnRfdGl0ZXIgPSB2ZGZfY291bnRfdGl0ZXJbIWR1cGxpY2F0ZWQodmRmX2NvdW50X3RpdGVyKSwgXQoKdmRmX2NvdW50X3RpdGVyJGxvZzEwdGl0ZXIgPSBsb2cxMCh2ZGZfY291bnRfdGl0ZXIkdGl0ZXIpCnZkZl9jb3VudF90aXRlciR0aXRlcltpcy5uYSh2ZGZfY291bnRfdGl0ZXIkdGl0ZXIpXSA9IDAKdmRmX2NvdW50X3RpdGVyJGxvZzEwdGl0ZXJbaXMubmEodmRmX2NvdW50X3RpdGVyJGxvZzEwdGl0ZXIpXSA9IDAKCgp2ZGZfY291bnRfdGl0ZXJfcGxvdCA9IGdncGxvdChmaWx0ZXIodmRmX2NvdW50X3RpdGVyLCBpbmZfcm91dGUgPT0gIkluZGV4IiB8IGluZl9yb3V0ZSA9PSAiQ29udGFjdCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBsb2cxMHRpdGVyLCB5ID0gbiwgY29sb3IgPSBkaWV0KSkgKwogIGdlb21fcG9pbnQoKSArCiAgeGxpbSgwLDcuNSkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJnbG0iKSArCiAgZmFjZXRfZ3JpZCh+aW5mX3JvdXRlKSArCiAgUGxvdFRoZW1lMSArCiAgRGlldGNvbFNjYWxlCnByaW50KHZkZl9jb3VudF90aXRlcl9wbG90KQpnZ3NhdmUoInZkZl9jb3VudF90aXRlcl9wbG90LnBkZiIsdmRmX2NvdW50X3RpdGVyX3Bsb3QscGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gNywgaGVpZ2h0ID0gNSkKYGBgCgpUYWxseWluZyBudW1iZXIgb2YgZmVycmV0cyB3aXRoIHZhcmlhbnRzCmBgYHtyfQpmZXJjb3VudCA9IHNlbGVjdCh2ZGYsc2FtcGxlLGZlcnJldElELERQSSxkaWV0LGluZl9yb3V0ZSkKZmVyY291bnQgPSBmZXJjb3VudFshZHVwbGljYXRlZChmZXJjb3VudCksIF0gICU+JSAKICB1bmlxdWUoKSAlPiUgCiAgZ3JvdXBfYnkoc2FtcGxlLGRpZXQsaW5mX3JvdXRlLERQSSkgJT4lIAogIHRhbGx5KCkKCiMgQ291bnRpbmcgdGhlIG51bWJlciBvZiBmZXJyZXRzIHdpdGggdmFyaWFudHMsIGp1c3QgYnkgZmVycmV0SUQgbm90IERQSQpmaWx0ZXIodmRmLCBkaWV0ID09ICJMZWFuIiAmIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSAlPiUgY291bnQoZmVycmV0SUQpCmZpbHRlcih2ZGYsIGRpZXQgPT0gIk9iZXNlIiAmIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSAlPiUgY291bnQoZmVycmV0SUQpCmZpbHRlcih2ZGYsIGRpZXQgPT0gIkxlYW4iICYgaW5mX3JvdXRlID09ICJDb250YWN0IikgJT4lIGNvdW50KGZlcnJldElEKQpmaWx0ZXIodmRmLCBkaWV0ID09ICJPYmVzZSIgJiBpbmZfcm91dGUgPT0gIkNvbnRhY3QiKSAlPiUgY291bnQoZmVycmV0SUQpCmBgYAoKUGxvdHRpbmcgZmVycmV0IHRhbGx5CmBgYHtyfQpnZ3Bsb3QoZmVyY291bnQsIGFlcyh4ID0gRFBJLCB5ID0gbiwgZmlsbCA9IGRpZXQpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAic3RhY2siKSArCiAgZmFjZXRfZ3JpZCh+aW5mX3JvdXRlKSArCiAgeWxhYigiTnVtYmVyIG9mIEZlcnJldHMgd2l0aCBTTlZzIikgKwogIFBsb3RUaGVtZTMgKwogIERpZXRjb2xTY2FsZV9maWxsCgpzbnZfY291bnQgPSBncm91cF9ieShmaWx0ZXIodmRmLCBpbmZfcm91dGUgPT0gIkluZGV4IiB8IGluZl9yb3V0ZSA9PSAiQ29udGFjdCIpLCBzYW1wbGUsIGZlcnJldElELCBEUEksaW5mX3JvdXRlLGRpZXQpICU+JQogIHRhbGx5KCkgJT4lCiAgZ2dwbG90KC4sIGFlcyh4ID0gbiwgZmlsbCA9IGRpZXQpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1KSArCiAgZmFjZXRfZ3JpZChkaWV0fmluZl9yb3V0ZSkgKwogIHhsYWIoIk51bWJlciBvZiB2YXJpYW50cyIpICsKICB5bGFiKCJOdW1iZXIgb2YgZmVycmV0cyIpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGVfZmlsbApwcmludChzbnZfY291bnQpCmdnc2F2ZSgiU05Wc19wZXJfZmVycmV0LnBkZiIsc252X2NvdW50LHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDksIGhlaWdodCA9IDUpCmBgYAoKYGBge3J9CnRyYW5zbWlzc2lvbl9pbmZvID0gIi9Vc2Vycy9tYXJpc3Nha25vbGwvRGVza3RvcC9HaXRIdWIvT2Jlc2l0eS9OZXdFeHRyYWN0aW9ucy9IOU4yL1RyYW5zbWlzc2lvblBhaXJzLmNzdiIKcGFpcnMgPSByZWFkLmNzdih0cmFuc21pc3Npb25faW5mbywgaGVhZGVyID0gVCkKCmZlcmNvdW50ID0gc2VwYXJhdGUoZmVyY291bnQsc2FtcGxlLGludG8gPSBjKCJmZXJyZXRJRCIsIkRQSSIpKQpmZXJjb3VudCA9IG1lcmdlKGZlcmNvdW50LCBwYWlycywgYnkgPSBjKCJmZXJyZXRJRCIpKQoKICAKcDEgPSBmZXJjb3VudCAlPiUgdW5pcXVlKCkgJT4lIAogICAgZ2dwbG90KC4sIGFlcyh4PSBEUEksIHkgPSBwYWlyX251bWJlcnMsIGZpbGwgPSBkaWV0KSkgKyAKICAgIGdlb21fdGlsZShjb2xvciA9ICdibGFjaycpICsgCiAgICBQbG90VGhlbWUzICsKICAgIERpZXRjb2xTY2FsZV9maWxsICsgCiAgICBmYWNldF9ncmlkKHBhaXJfZGlldHN+aW5mX3JvdXRlLCBzY2FsZXMgPSAnZnJlZScsIHNwYWNlID0gJ2ZyZWUnKQpwcmludChwMSkKZ2dzYXZlKCJmZXJyZXRzX3RpbGVwbG90LnBkZiIsIHAxLCBwYXRoID0gc2F2ZWRpciwpCmBgYAoKYGBge3J9Cm0yID0gZmlsdGVyKG1ldGEsIHRpdGVyICE9ICJOQSIgJiB0aXRlciAhPSAic2FjcmlmaWNlZCIpICU+JQogIGZpbHRlcihEUEkgPT0gImQwMiIgfCBEUEkgPT0gImQwNCIgfCBEUEkgPT0gImQwNiIgfCBEUEkgPT0gImQwOCIgfCBEUEkgPT0gImQxMCIgfCBEUEkgPT0gImQxMiIpCnRpdGVyc19wYWlycyA9IG1lcmdlKG0yLHBhaXJzLCBieSA9IGMoImZlcnJldElEIiksIGFsbC54ID0gVFJVRSkKCnRpdGVyc19wYWlycyA9IGdyb3VwX2J5KHRpdGVyc19wYWlycyxpbmZfcm91dGUsIGRpZXQsIERQSSxwYWlyX2RpZXRzKSAlPiUKICBtdXRhdGUoYXZnX3RpdGVyID0gbWVhbih0aXRlcikpICU+JQogIG11dGF0ZShzZF90aXRlciA9IHNkKHRpdGVyKSkgJT4lCiAgbXV0YXRlKGF2Z19sb2dfdGl0ZXIgPSBtZWFuKGxvZzEwX3RpdGVyKSkgJT4lCiAgdW5ncm91cCgpCgp0aXRlcnNfcGFpcnNfcGxvdCA9IGdncGxvdCh0aXRlcnNfcGFpcnMsIGFlcyh4ID0gRFBJLCB5ID0gYXZnX2xvZ190aXRlciwgY29sb3IgPSBkaWV0KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGluZl9yb3V0ZSkpICsKICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gMSkpICsKICBmYWNldF9ncmlkKGluZl9yb3V0ZStkaWV0fnBhaXJfZGlldHMpICsKICBEaWV0Y29sU2NhbGUgKwogIHlsaW0oMCw4KSArCiAgUGxvdFRoZW1lMQpwcmludCh0aXRlcnNfcGFpcnNfcGxvdCkKZ2dzYXZlKCJ0aXRlcnNfcGFpcnNfcGxvdC5wZGYiLHRpdGVyc19wYWlyc19wbG90LHBhdGg9c2F2ZWRpcikKYGBgCgpQbG90dGluZyByZXAxIHZzIHJlcDIKYGBge3J9CnJlcF9jb3JyZWxhdGlvbiA9IGdncGxvdCh2ZGYpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gbWlub3JmcmVxMSwgeSA9IG1pbm9yZnJlcTIpKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IG1ham9yZnJlcTEsIHkgPSBtYWpvcmZyZXEyKSkgKwogIFBsb3RUaGVtZTEgKwogIHhsYWIoIkFsbGVsZSBmcmVxdWVuY3kgaW4gcmVwbGljYXRlIDEiKSArCiAgeWxhYigiQWxsZWxlIGZyZXF1ZW5jeSBpbiByZXBsaWNhdGUgMiIpICsKICB4bGltKDAsMC41NSkgKyB5bGltKDAsMC41NSkKcHJpbnQocmVwX2NvcnJlbGF0aW9uKQpnZ3NhdmUoInJlcF9jb3JyZWxhdGlvbi5wZGYiLHJlcF9jb3JyZWxhdGlvbixwYXRoID0gc2F2ZWRpcikKYGBgCgpDb25zZW5zdXMgY2hhbmdlcwpgYGB7cn0KY29uX2NoYW5nZSA9IGZpbHRlcih2ZGYsIHN0b2NrbnQgIT0gbWFqb3IpICU+JQogIGZpbHRlcihtYWpvciAlaW4lIG50bGlzdCkKY29uX2NoYW5nZSA9IGNvbl9jaGFuZ2VbIWR1cGxpY2F0ZWQoY29uX2NoYW5nZSksIF0KbnJvdyhjb25fY2hhbmdlKQoKY29uX2NoYW5nZSRtYWogPSBwYXN0ZTAoY29uX2NoYW5nZSRzZWdtZW50LCJfIixjb25fY2hhbmdlJHN0b2NrLGNvbl9jaGFuZ2UkbnRwb3MpCmNvbl9jaGFuZ2UkZmVycmV0SURfbWFqID0gcGFzdGUwKGNvbl9jaGFuZ2UkZmVycmV0SUQsIl8iLGNvbl9jaGFuZ2UkbWFqKQpjb25fY2hhbmdlID0gY29uX2NoYW5nZVshZHVwbGljYXRlZChjb25fY2hhbmdlJGZlcnJldElEX21haiksXSAKIyBub3QgY291bnRpbmcgc2FtZSBjb25zZW5zdXMgY2hhbmdlIGJ1dCBqdXN0IG9uIGRpZmZlcmVudCBkYXlzIC0gYmFzaWNhbGx5IGNvdW50aW5nIHVuaXF1ZSBjb25zZW5zdXMgY2hhbmdlcwoKbnJvdyhjb25fY2hhbmdlKQpjb25zID0gY291bnQoY29uX2NoYW5nZSxmZXJyZXRJRCxkaWV0LGluZl9yb3V0ZSkKCnNlbGVjdChjb25fY2hhbmdlLCBzdG9ja250LCBtYWpvciwgbWlub3IpCiMgaW4gYWxsIGNhc2VzLCB0aGUgc3RvY2tudCBpcyB0aGUgbWlub3IgLT4gaGFzIGJlZW4gcmVwbGFjZWQgYnkgYW5vdGhlciBudAojIGRpZCB0aGVzZSBhcmlzZSBhcyBtaW5vcnMgZmlyc3Q/CmBgYAoKUGxvdHRpbmcgY29uc2Vuc3VzIGNoYW5nZXMKYGBge3J9CmdncGxvdChmaWx0ZXIoY29uX2NoYW5nZSwgcXVhbGl0eSA9PSAiZ29vZCIsIGluZl9yb3V0ZSA9PSAiQ29udGFjdCIpLCBhZXMoeCA9IERQSSwgeSA9IG1ham9yZnJlcSwgY29sb3IgPSBkaWV0KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZmFjZXRfZ3JpZChpbmZfcm91dGV+ZmVycmV0SUQpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKCmdyb3VwX2J5KGNvbl9jaGFuZ2UsIGRpZXQsIGluZl9yb3V0ZSxmZXJyZXRJRCwgRFBJKSAlPiUKICB0YWxseSgpCmBgYAoKYGBge3J9CmNvbl9jaGFuZ2UkdmFyID0gcGFzdGUwKGNvbl9jaGFuZ2UkZmVycmV0SUQsIl8iLGNvbl9jaGFuZ2Ukc2VnbWVudCwiXyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbl9jaGFuZ2UkbWFqb3IsIl8iLGNvbl9jaGFuZ2UkbnRwb3MsIl8iLGNvbl9jaGFuZ2UkbWlub3IpCmNvbnNlbnN1cyA9IHVuaXF1ZShjb25fY2hhbmdlJHZhcikKbGVuZ3RoKGNvbnNlbnN1cykKYGBgCgpgYGB7cn0KdmRmJHZhciA9IHBhc3RlMCh2ZGYkZmVycmV0SUQsIl8iLHZkZiRzZWdtZW50LCJfIix2ZGYkbWFqb3IsIl8iLHZkZiRudHBvcywiXyIsdmRmJG1pbm9yKQoKbWlub3J2ZGYgPSBmaWx0ZXIodmRmLCAhKHZhciAlaW4lIGNvbnNlbnN1cykpCm1pbm9ydmRmID0gbWlub3J2ZGZbIWR1cGxpY2F0ZWQobWlub3J2ZGYpLCBdCm5yb3codmRmKSAtIG5yb3cobWlub3J2ZGYpCmBgYAoKTG9hZGluZyBpbiB0cmFubWlzc2lvbiBkYXRhCmBgYHtyfQp0cmFuc21pc3Npb24gPSAiLi9UcmFuc21pc3Npb25QYWlycy5jc3YiCnBhaXJzID0gcmVhZC5jc3YoZmlsZSA9IHRyYW5zbWlzc2lvbiwgaGVhZGVyID0gVCwgc2VwID0gIiwiKQoKdmRmX3BhaXJzID0gbWVyZ2UodmRmLCBwYWlycywgYnkgPSBjKCJmZXJyZXRJRCIpKQpgYGAKCkNhbiB0aGUgY29uc2Vuc3VzIGNoYW5nZXMgYmUgZGV0ZWN0ZWQgYXMgbWlub3IgdmFyaWFudHMgZmlyc3Q/CmBgYHtyfQptYWpwb3MgPSBjKCJIOU4yX05QXzMyNiIsIkg5TjJfUEIxXzE4ODIiLCJIOU4yX0hBXzI4NCIsIkg5TjJfUEIxXzk2NSIsCiAgICAgICAgICAgIkg5TjJfTlNfNjUyIiwiSDlOMl9QQV8xNDgzIiwiSDlOMl9IQV83NDciLCJIOU4yX1BCMl82MzkiLAogICAgICAgICAgICJIOU4yX1BCMV8xODgyIikKICAKbWlub3J2ZGYkdmFyID0gcGFzdGUwKG1pbm9ydmRmJHNlZ21lbnQsIl8iLG1pbm9ydmRmJG50cG9zKQpwb3NfbWlub3JzID0gZmlsdGVyKG1pbm9ydmRmLCB2YXIgJWluJSBtYWpwb3MpICU+JQogIHNlbGVjdCgtYygic2hhbm5vbl9udHBvcyIsInNlZ21lbnRfc2hhbiIsInNoYW5ub24iLCJzaGFubm9uX3BlcmtiIiwibm9ybWFsaXplZF9zaGFubm9uIikpCnBvc19taW5vcnMkZnJlcSA9IHBvc19taW5vcnMkbWlub3JmcmVxCnBvc19taW5vcnMgPSBwb3NfbWlub3JzWyFkdXBsaWNhdGVkKHBvc19taW5vcnMpLCBdICU+JSBkcm9wbGV2ZWxzKCkKCnBvc19tYWpvcnMgPSBjb25fY2hhbmdlICU+JSBzZWxlY3QoIWMoIm1haiIsImZlcnJldElEX21haiIpKQpwb3NfbWFqb3JzJHZhciA9IHBhc3RlMChwb3NfbWFqb3JzJHNlZ21lbnQsIl8iLHBvc19tYWpvcnMkbnRwb3MpCnBvc19tYWpvcnMkZnJlcSA9IHBvc19tYWpvcnMkbWFqb3JmcmVxCgphbGxfcG9zID0gcmJpbmQocG9zX21ham9ycyxwb3NfbWlub3JzKSAlPiUgZHJvcGxldmVscygpCmFsbF9wb3Mkc2VnbWVudCA9IGZhY3RvcihhbGxfcG9zJHNlZ21lbnQsIGxldmVscyA9IFNFR01FTlRTKQphbGxfcG9zJGRpZXQgPSBmYWN0b3IoYWxsX3BvcyRkaWV0LCBsZXZlbHMgPSBjKCJPYmVzZSIsIkxlYW4iKSkKCmFsbF9wb3MgPSBmaWx0ZXIoYWxsX3BvcywgZmVycmV0SUQgPT0gIjE0MDkifAogICAgICAgICAgICAgICAgZmVycmV0SUQgPT0gIjE3ODkifCBmZXJyZXRJRCA9PSAiMTc5NCJ8CiAgICAgICAgICAgICAgICBmZXJyZXRJRCA9PSAiMTgwMSJ8IGZlcnJldElEID09ICIxNzk3InwKICAgICAgICAgICAgICAgIGZlcnJldElEID09ICIxOTcxInwgZmVycmV0SUQgPT0gIjE5ODAifAogICAgICAgICAgICAgICAgZmVycmV0SUQgPT0gIjE5NzMifCBmZXJyZXRJRCA9PSAiMTk4NiJ8CiAgICAgICAgICAgICAgICBmZXJyZXRJRCA9PSAiMjI1MyJ8IGZlcnJldElEID09ICIyMjMxInwKICAgICAgICAgICAgICAgIGZlcnJldElEID09ICIyMjMzInwgZmVycmV0SUQgPT0gIjIyMzIifAogICAgICAgICAgICAgICAgZmVycmV0SUQgPT0gIjIyNTQifCBmZXJyZXRJRCA9PSAiMjIzOCIpCgphbGxfcG9zID0gbWVyZ2UoYWxsX3BvcywgcGFpcnMpCgptaW5vcnRvY29uX3Bsb3QgPSBnZ3Bsb3QoZmlsdGVyKGFsbF9wb3MsIHBhaXJfbnVtYmVycyA9PSAiMTQwOC0xNDA5IiksIAogICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBEUEksIHkgPSBmcmVxLCBjb2xvciA9IHZhcikpICsKICBnZW9tX3BvaW50KHNpemUgPSAyKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHZhcikpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjUsIGxpbmV0eXBlID0gImRvdHRlZCIsIGNvbG9yID0gInJlZCIpICsKICBmYWNldF9ncmlkKHBhaXJfbnVtYmVyc35pbmZfcm91dGUsIGRyb3AgPSBGQUxTRSkgKwogIFBsb3RUaGVtZTEKcHJpbnQobWlub3J0b2Nvbl9wbG90KQpnZ3NhdmUoIm1pbm9ydG9jb25fcGxvdC5wZGYiLG1pbm9ydG9jb25fcGxvdCxwYXRoID0gc2F2ZWRpciwgaGVpZ2h0ID0gNSwgd2lkdGggPSAxMCkKCmBgYAoKVGFsbHlpbmcgU05WcwpgYGB7cn0KIyBjYW4gbWFrZSB0aGVzZSBncm91cGluZ3Mgd2hhdGV2ZXIgeW91IHdhbnQKCiMgY291bnQgdGhlIG51bWJlciBvZiBTTlZzIHBlciBzYW1wbGUKZ3JvdXBfbGlzdF9zZWcgPSBjKCdmZXJyZXRJRCcsJ3NlZ21lbnQnLCJEUEkiLCJkaWV0IiwiaW5mX3JvdXRlIiwiY29ob3J0IikgIyBjb3VudHMgYWNyb3NzIGVhY2ggc2VnbWVudCAKZ3JvdXBfbGlzdF9nZW4gPSBjKCdmZXJyZXRJRCcsIkRQSSIsImRpZXQiLCJpbmZfcm91dGUiLCJjb2hvcnQiKSAjIENvdW50cyBhY3Jvc3MgZW50aXJlIGdlbm9tZQoKc2VnX2NvdW50ID0gVGFsbHlJdChtaW5vcnZkZiwgZ3JvdXBfbGlzdF9zZWcsICJzbnZfY291bnQiKQpnZW5fY291bnQgPSBUYWxseUl0KG1pbm9ydmRmLCBncm91cF9saXN0X2dlbiwgInNudl9jb3VudCIpIApgYGAKCmBgYHtyfQojIElOQ0xVRElORyBTRUdNRU5UUyBXSVRIIE5PIFNOVlMgLSBidXQgb25seSB1c2luZyB0aG9zZSB0aGF0IHBhc3NlZCBzZXEgY3V0b2ZmCnJlc2VxX3NlZyA9IHNlbGVjdChtZXRhLGZlcnJldElELHNlZ21lbnQsRFBJLGRpZXQsaW5mX3JvdXRlLGNvaG9ydCwgcXVhbGl0eSkgJT4lIAogIGZpbHRlcihxdWFsaXR5ID09ICJnb29kIikgJT4lIAogIHVuaXF1ZSgpCnNlZ19jb3VudCA9IG1lcmdlKHNlZ19jb3VudCxyZXNlcV9zZWcsIGFsbD0gVFJVRSkKc2VnX2NvdW50ID0gc2VnX2NvdW50WyFkdXBsaWNhdGVkKHNlZ19jb3VudCksIF0KCnNlZ19jb3VudCRzbnZfY291bnRbaXMubmEoc2VnX2NvdW50JHNudl9jb3VudCldID0gMApzZWdfY291bnQgPSBmaWx0ZXIoc2VnX2NvdW50LCAhaXMubmEoZmVycmV0SUQpKQpgYGAKCmBgYHtyfQpyZXNlcV9nZW4gPSBzZWxlY3QobWV0YSxmZXJyZXRJRCxEUEksZGlldCxpbmZfcm91dGUsY29ob3J0LHF1YWxpdHkpICU+JSAKICBmaWx0ZXIocXVhbGl0eSA9PSAiZ29vZCIpICU+JSAKICB1bmlxdWUoKQpnZW5fY291bnQgPSBtZXJnZShnZW5fY291bnQscmVzZXFfZ2VuLCBhbGwgPSBUUlVFKQpnZW5fY291bnQgPSBnZW5fY291bnRbIWR1cGxpY2F0ZWQoZ2VuX2NvdW50KSwgXQoKZ2VuX2NvdW50JHNudl9jb3VudFtpcy5uYShnZW5fY291bnQkc252X2NvdW50KV0gPSAwCmdlbl9jb3VudCA9IGZpbHRlcihnZW5fY291bnQsICFpcy5uYShmZXJyZXRJRCkpCmBgYAoKYGBge3J9CiMgQXZlcmFnZSBOdW1iZXIgb2YgVmFyaWFudHMgcGVyIFNhbXBsZQpnZW5fY291bnRfYXZnID0gZ3JvdXBfYnkoZ2VuX2NvdW50LCBEUEksIGRpZXQsIGluZl9yb3V0ZSkgJT4lCiAgbXV0YXRlKGF2Z1NOViA9IG1lYW4oc252X2NvdW50KSwgc2RTTlYgPSBzZChzbnZfY291bnQpKQoKc2VnX2NvdW50X2F2ZyA9IGdyb3VwX2J5KHNlZ19jb3VudCwgRFBJLCBkaWV0KSAlPiUKICBtdXRhdGUoYXZnU05WID0gbWVhbihzbnZfY291bnQpLCBzZFNOViA9IHNkKHNudl9jb3VudCkpCmBgYAoKQ2FsY3VsYXRpbmcgU2hhbm5vbiBFbnRyb3B5CmBgYHtyfQptaW5vcnZkZiA9IFNoYW5ub25Qb3MobWlub3J2ZGYpCm1pbm9ydmRmJFNlZ21lbnRTaXplID0gYXMubnVtZXJpYyhtaW5vcnZkZiRTZWdtZW50U2l6ZSkKbWlub3J2ZGYkc2hhbm5vbl9wZXJrYiA9IChtaW5vcnZkZiRzZWdtZW50X3NoYW4vKG1pbm9ydmRmJFNlZ21lbnRTaXplLzEwMDApKQptaW5vcnZkZiRub3JtYWxpemVkX3NoYW5ub24gPSAobWlub3J2ZGYkc2hhbm5vbi9HZW5vbWVTaXplKQpgYGAKCmBgYHtyfQojIHNoYW5ub25fbnRwb3MgPSBzaGFubm9uIGVudHJvcHkgYXQgdGhhdCBudCBwb3MgLSBzaG91bGQgYWx3YXlzIGJlIGJldHdlZW4gMCBhbmQgMSBmb3IgZWFjaCBzYW1wbGUKIyBzZWdtZW50X3NoYW4gPSBzdW0gb2YgYWxsIG50X3BvcyBwZXIgc2VnbWVudCBmb3IgZWFjaCBzYW1wbGUKIyBzaGFubm9uID0gc3VtIG9mIGFsbCBzZWdtZW50X3NoYW4gYWNyb3NzIGdlbm9tZSBmb3IgZWFjaCBzYW1wbGUKIyBzaGFubm9uX3BlcmtiID0gc2VnbWVudCBzaGFubm9uIHBlciBrYiAoc2VnbWVudCBzcGVjaWZpYykgZm9yIGVhY2ggc2FtcGxlCiMgbm9ybWFsaXplZF9zaGFubm9uID0gc2hhbm5vbiBkaXZpZGVkIGJ5IGdlbm9tZSBzaXplIChjYW4gbWFrZSBwZXIga2IgYnkgZGl2aWRpbmcgYnkgMTAwMCkgZm9yIGVhY2ggc2FtcGxlCmBgYAoKYGBge3J9CiMgQXZlcmFnZSBTaGFubm9uIEVudHJvcHkgcGVyIFNpdGUgcGVyIFNhbXBsZSAodXNpbmcgbm9ybWFsaXplZF9zaGFubm9uKQpzaGFuX2cgPSB1bmdyb3VwKG1pbm9ydmRmKSAlPiUKICBzZWxlY3QoZmVycmV0SUQsIERQSSwgZGlldCwgaW5mX3JvdXRlLCBjb2hvcnQsbm9ybWFsaXplZF9zaGFubm9uKSAlPiUKICB1bmlxdWUoKQpzaGFuX2cgPSBtZXJnZShzaGFuX2cscmVzZXFfZ2VuICU+JSB1bmlxdWUoKSwgYnkgPSBjKCJmZXJyZXRJRCIsICJEUEkiLCAiZGlldCIsICJpbmZfcm91dGUiLCJjb2hvcnQiKSwgYWxsPSBUUlVFKSAlPiUKICBmaWx0ZXIoaW5mX3JvdXRlID09ICJJbmRleCIgfCBpbmZfcm91dGUgPT0gIkNvbnRyb2wiKSAlPiUgCiAgdW5pcXVlKCkKc2hhbl9nJG5vcm1hbGl6ZWRfc2hhbm5vbltpcy5uYShzaGFuX2ckbm9ybWFsaXplZF9zaGFubm9uKV0gPSAwCgpkaW0oc2hhbl9nKQpzaGFuX2cgPC0gc2hhbl9nW2NvbXBsZXRlLmNhc2VzKHNoYW5fZyksIF0gCmRpbShzaGFuX2cpCgpzaGFuX2dlbl9wbG90ID0gZ2dwbG90KGZpbHRlcihzaGFuX2csIERQSSA9PSAiZDAyIiB8IERQSSA9PSAiZDA0IiB8IERQSSA9PSAiZDA2IiB8IERQSSA9PSAiU3RvY2siKSwgCiAgICAgICBhZXMoeCA9IGRpZXQsIHkgPSBub3JtYWxpemVkX3NoYW5ub24vMTAwMCkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFlcyhjb2xvciA9IGRpZXQpKSArCiAgZmFjZXRfZ3JpZCh+RFBJKSArCiAgUGxvdFRoZW1lMSArCiAgRGlldGNvbFNjYWxlCnByaW50KHNoYW5fZ2VuX3Bsb3QpCmdnc2F2ZSgic2hhbl9nZW5fcGxvdC5wZGYiLCBzaGFuX2dlbl9wbG90LCBwYXRoID0gc2F2ZWRpciwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSkKYGBgCgpUZXN0IGZvciBzaWduaWZpY2FuY2UKYGBge3J9Cm8gPSBmaWx0ZXIoc2hhbl9nLCBEUEkgPT0gIlN0b2NrIiAmIGRpZXQgPT0gIkNvbnRyb2wiKQpsID0gZmlsdGVyKHNoYW5fZywgRFBJID09ICJkMDYiICYgZGlldCA9PSAiTGVhbiIpCnQudGVzdChvJG5vcm1hbGl6ZWRfc2hhbm5vbixsJG5vcm1hbGl6ZWRfc2hhbm5vbikKYGBgCgpgYGB7cn0Kc2hhbl9nX2F2ZyA9IGdyb3VwX2J5KHNoYW5fZywgRFBJLCBkaWV0LCBpbmZfcm91dGUpICU+JSAKICBtdXRhdGUoYXZnU2hhbiA9IG1lYW4obm9ybWFsaXplZF9zaGFubm9uKSwgc2RTaGFuID0gc2Qobm9ybWFsaXplZF9zaGFubm9uKSkKYGBgCgpgYGB7cn0Kc2hhbl9zZWdrYiA9IHVuZ3JvdXAobWlub3J2ZGYpICU+JQogIHNlbGVjdChmZXJyZXRJRCwgRFBJLCBkaWV0LCBpbmZfcm91dGUsIHNlZ21lbnQsIHNoYW5ub25fcGVya2IpCnNoYW5fc2Vna2IgPSBzaGFuX3NlZ2tiWyFkdXBsaWNhdGVkKHNoYW5fc2Vna2IpLF0Kc2hhbl9zZWdrYl9hdmcgPSBncm91cF9ieShzaGFuX3NlZ2tiLCBEUEksIGRpZXQsIGluZl9yb3V0ZSwgc2VnbWVudCkgJT4lIAogIG11dGF0ZShhdmdTaGFuID0gbWVhbihzaGFubm9uX3BlcmtiKSwgc2RTaGFuID0gc2Qoc2hhbm5vbl9wZXJrYikpIAojIGdpdmVzIGEgZ2Vub21lLXdpZGUgYXZlcmFnZSBvZiBub3JtYWxpemVkIHNlZ21lbnQgc2hhbm5ub25zIGZvciBldmVyeSBzYW1wbGUKCmBgYAoKTWFraW5nIHBsb3RzIGZvciB2YXJpYW50IHRhbGxpZXMgYW5kIFNoYW5ub24gZW50cm9weSAKYGBge3J9ClZhclBsb3QgPSBnZ3Bsb3QoZ2VuX2NvdW50X2F2ZywgYWVzKHg9RFBJLCBmaWxsID0gZGlldCkpICsKICBnZW9tX2NvbChhZXMoeSA9IGF2Z1NOViwgZ3JvdXAgPSBkaWV0KSwgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgZ2VvbV9qaXR0ZXIoYWVzKGdyb3VwID0gZGlldCwgeSA9IHNudl9jb3VudCksIHdpZHRoICA9IDAuMTUsIHNpemUgPSAyKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGF2Z1NOViAtIHNkU05WLAogICAgICAgICAgICAgICAgICAgIHltYXggPSBhdmdTTlYgKyBzZFNOVikpICsKICB5bGFiKCJBdmVyYWdlIG51bWJlciBvZiBTTlZzIHBlciBzYW1wbGUiKSArCiAgeGxhYigiRGF5cyBhZnRlciBpbmZlY3Rpb24iKSArCiAgZmFjZXRfZ3JpZCh+aW5mX3JvdXRlK2RpZXQpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGVfZmlsbApwcmludChWYXJQbG90KQpnZ3NhdmUoVmFyUGxvdCwgZmlsZSA9ICJWYXJpYW50Q291bnQucGRmIiwgcGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gMjUsIGhlaWdodCA9IDEwKQpgYGAKCmBgYHtyfQpTaGFubm9uUGxvdCA9IGdncGxvdChzaGFuX2dfYXZnLCBhZXMoeD1EUEksIGZpbGwgPSBkaWV0KSkgKwogIGdlb21fY29sKGFlcyh5ID0gYXZnU2hhbiwgZ3JvdXAgPSBkaWV0KSwgcG9zaXRpb24gPSAiZG9kZ2UiKSArICNwbG90cyBhdmVyYWdlCiAgZ2VvbV9qaXR0ZXIoYWVzKHkgPSBub3JtYWxpemVkX3NoYW5ub24sIGdyb3VwID0gZGlldCksIHdpZHRoICA9IDAuMTUpICsgI3Bsb3RzIHZhbHVlIGZvciBlYWNoIHNhbXBsZQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBhdmdTaGFuIC0gc2RTaGFuLAogICAgICAgICAgICAgICAgICAgIHltYXggPSBhdmdTaGFuICsgc2RTaGFuKSkgKwogIHlsYWIoIkF2ZXJhZ2UgU2hhbm5vbiBlbnRyb3B5IHBlciBzaXRlIGFjcm9zcyBnZW5vbWUiKSArCiAgZmFjZXRfZ3JpZCh+aW5mX3JvdXRlK2RpZXQpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGVfZmlsbApwcmludChTaGFubm9uUGxvdCkKZ2dzYXZlKFNoYW5ub25QbG90LCBmaWxlID0gIk1lYW5TaGFuUGVyU2l0ZS5wZGYiLCBwYXRoID0gc2F2ZWRpcikKClNoYW5ub25QbG90MiA9IGdncGxvdChzaGFuX3NlZ2tiX2F2ZywgYWVzKHg9RFBJLCBmaWxsID0gZGlldCkpICsKICBnZW9tX2NvbChhZXMoeSA9IGF2Z1NoYW4sIGdyb3VwID0gZGlldCksIHBvc2l0aW9uID0gImRvZGdlIikgKyAjIHBsb3RzIGF2ZXJhZ2UKICAjZ2VvbV9wb2ludChhZXMoeSA9IHNoYW5ub25fcGVya2IsIGdyb3VwID0gZGlldCkpICsgIyBwbG90cyB2YWx1ZSBmb3IgZWFjaCBzZWdtZW50LCBzYW1wbGUKICAjZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGF2Z1NoYW4gLSBzZFNoYW4sCiAgIyAgICAgICAgICAgICAgICAgIHltYXggPSBhdmdTaGFuICsgc2RTaGFuKSkgKwogIHlsYWIoIkF2ZXJhZ2UgU2hhbm5vbiBlbnRyb3B5IHBlciBrQiBhY3Jvc3Mgc2VnbWVudHMiKSArCiAgZmFjZXRfZ3JpZCh+c2VnbWVudCkgKwogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZV9maWxsCnByaW50KFNoYW5ub25QbG90MikKZ2dzYXZlKFNoYW5ub25QbG90MiwgZmlsZSA9ICJNZWFuU2hhblBlclNlZ0tCLnBkZiIsIHBhdGggPSBzYXZlZGlyKQpgYGAKCmBgYHtyfQpzaGFuX3NlZ19wbG90ID0gZmlsdGVyKHNoYW5fc2Vna2IsIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSAlPiUgCiAgZmlsdGVyKERQSSA9PSAiZDAyIiB8IERQSSA9PSAiZDA0IiB8IERQSSA9PSAiZDA2IikgJT4lCiAgZ2dwbG90KC4gLCBhZXMoeCA9IHNlZ21lbnQsIHkgPSBzaGFubm9uX3BlcmtiLCBjb2xvciA9IGRpZXQpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGZhY2V0X2dyaWQofkRQSSkgKwogIFBsb3RUaGVtZTEgKwogIHlsYWIoIlNoYW5ub24gZW50cm9weSBwZXIga2IgYWNyb3NzIGVhY2ggc2VnbWVudCIpICsKICBEaWV0Y29sU2NhbGUKcHJpbnQoc2hhbl9zZWdfcGxvdCkKZ2dzYXZlKCJzaGFuX3NlZ19wbG90LnBkZiIsc2hhbl9zZWdfcGxvdCxwYXRoPXNhdmVkaXIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDUpCgpzaGFuX2dlbl9wbG90ID0gZmlsdGVyKHNoYW5fZ19hdmcsIGluZl9yb3V0ZSA9PSAiSW5kZXgiIHwgaW5mX3JvdXRlID09ICJDb250cm9sIikgJT4lIAogIGZpbHRlcihEUEkgPT0gImQwMiIgfCBEUEkgPT0gImQwNCIgfCBEUEkgPT0gImQwNiIgfCBEUEkgPT0gImQwOCIgfCBEUEkgPT0gIlN0b2NrIikgJT4lCiAgZ2dwbG90KC4gLCBhZXMoeCA9IGRpZXQsIHkgPSAobm9ybWFsaXplZF9zaGFubm9uLzEwMDApLCBjb2xvciA9IGRpZXQpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4xKSArCiAgZmFjZXRfZ3JpZCh+RFBJKSArCiAgUGxvdFRoZW1lMSArCiAgeWxhYigiU2hhbm5vbiBlbnRyb3B5IHBlciBrYiBhY3Jvc3MgZWFjaCBnZW5vbWUiKSArCiAgRGlldGNvbFNjYWxlCnByaW50KHNoYW5fZ2VuX3Bsb3QpCmdnc2F2ZSgic2hhbl9nZW5fcGxvdC5wZGYiLHNoYW5fZ2VuX3Bsb3QscGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDUpCgpgYGAKVCB0ZXN0cyBmb3IgcGxvdHMKYGBge3J9Cm8gPSBmaWx0ZXIoc2hhbl9zZWdrYiwgaW5mX3JvdXRlID09ICJJbmRleCIgJiBEUEkgPT0gImQwMiIgJiBkaWV0ID09ICJPYmVzZSIgJiBzZWdtZW50ID09ICJIOU4yX05TIikKbCA9IGZpbHRlcihzaGFuX3NlZ2tiLCBpbmZfcm91dGUgPT0gIkluZGV4IiAmIERQSSA9PSAiZDAyIiAmIGRpZXQgPT0gIkxlYW4iICYgc2VnbWVudCA9PSAiSDlOMl9OUyIpCnQudGVzdChvJHNoYW5ub25fcGVya2IsbCRzaGFubm9uX3BlcmtiKQoKIyBPbiBkYXkgNCwgdGhlcmUgaXMgc2lnbmlmaWNhbnRseSBoaWdoZXIgZGl2ZXJzaXR5IGluIE5QIGluIGxlYW4gZmVycmV0cyAocCA9IDAuMDYzMzkpCiMgT24gZGF5IDQsIHRoZXJlIGlzIHNpZ25pZmljYW50bHkgaGlnaGVyIGRpdmVyc2l0eSBpbiBNUCBpbiBsZWFuIGZlcnJldHMgKHAgPSAwLjA5NTczKQojIE9uIGRheSA0LCB0aGVyZSBpcyBzaWduaWZpY2FudGx5IGhpZ2hlciBkaXZlcnNpdHkgaW4gTlMgaW4gbGVhbiBmZXJyZXRzIChwID0gMC4wMDQ3NDQpCgojIE9uIGRheSA2LCB0aGVyZSBpcyBzaWduaWZpY2FudGx5IGhpZ2hlciBkaXZlcnNpdHkgaW4gTkEgaW4gbGVhbiBmZXJyZXRzIChwID0gMC4wMDgxOTkpCmBgYAoKYGBge3J9Cm8gPSBmaWx0ZXIoc2hhbl9nX2F2ZywgaW5mX3JvdXRlID09ICJJbmRleCIgJiBEUEkgPT0gImQwNiIgJiBkaWV0ID09ICJPYmVzZSIpCmwgPSBmaWx0ZXIoc2hhbl9nX2F2ZywgaW5mX3JvdXRlID09ICJJbmRleCIgJiBEUEkgPT0gImQwNiIgJiBkaWV0ID09ICJMZWFuIikKdC50ZXN0KG8kbm9ybWFsaXplZF9zaGFubm9uLGwkbm9ybWFsaXplZF9zaGFubm9uKQoKIyBPbiBkYXkgNiwgdGhlcmUgaXMgc2lnbmlmaWNhbnRseSBoaWdoZXIgZGl2ZXJzaXR5IChTaGFubm9uL2tiIGZvciBlYWNoIGdlbm9tZSkgaW4gbGVhbiBmZXJyZXRzIChwID0gMC4wNTYwNykKYGBgCgpgYGB7cn0KZ2VuX2NvdW50X2F2ZyA9IGZpbHRlcihnZW5fY291bnRfYXZnLCBpbmZfcm91dGUgPT0gIkluZGV4IiB8IGluZl9yb3V0ZSA9PSAiQ29udGFjdCIpCkxlYW5TTlZzX3BlckZlcnJldCA9IGdncGxvdChmaWx0ZXIoZ2VuX2NvdW50X2F2ZywgZGlldCA9PSAiTGVhbiIgJiBEUEkgIT0gImQxMiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gRFBJLCB5ID0gc252X2NvdW50LCBjb2xvciA9IGZlcnJldElEKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGZlcnJldElEKSkgKwogIHlsaW0oMCw0NSkgKwogIGZhY2V0X2dyaWQofmRpZXQraW5mX3JvdXRlKSsgCiAgUGxvdFRoZW1lMSAKcHJpbnQoTGVhblNOVnNfcGVyRmVycmV0KQpnZ3NhdmUoIkxlYW5TTlZzX3BlckZlcnJldC5wbmciLCBMZWFuU05Wc19wZXJGZXJyZXQsIHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQoKT2Jlc2VTTlZzX3BlckZlcnJldCA9IGdncGxvdChmaWx0ZXIoZ2VuX2NvdW50X2F2ZywgZGlldCA9PSAiT2Jlc2UiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBEUEksIHkgPSBzbnZfY291bnQsIGNvbG9yID0gZmVycmV0SUQpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gZmVycmV0SUQpKSArCiAgICB5bGltKDAsNDUpICsKICBmYWNldF9ncmlkKH5kaWV0K2luZl9yb3V0ZSkgKyAKICBQbG90VGhlbWUxCnByaW50KE9iZXNlU05Wc19wZXJGZXJyZXQpCmdnc2F2ZSgiT2Jlc2VTTlZzX3BlckZlcnJldC5wbmciLCBPYmVzZVNOVnNfcGVyRmVycmV0LCBwYXRoID0gc2F2ZWRpciwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSkKYGBgCgpgYGB7cn0Kc252X2NvdW50X3NlZ21lbnRfcGxvdCA9IGZpbHRlcihzZWdfY291bnQsIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSAlPiUgCiAgZmlsdGVyKERQSSA9PSAiZDAyIiB8IERQSSA9PSAiZDA0IiB8IERQSSA9PSAiZDA2IikgJT4lCgpnZ3Bsb3QoLiAsIGFlcyh4ID0gc2VnbWVudCwgeSA9IHNudl9jb3VudCwgY29sb3IgPSBkaWV0KSkgKwogIGdlb21fYm94cGxvdCgpICsKICAjZ2VvbV9wb2ludCgpICsKICBmYWNldF9ncmlkKH5EUEkpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKcHJpbnQoc252X2NvdW50X3NlZ21lbnRfcGxvdCkKZ2dzYXZlKCJzbnZfY291bnRfc2VnbWVudF9wbG90LnBkZiIsIHNudl9jb3VudF9zZWdtZW50X3Bsb3QsIHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQoKCmdlbl9jb3VudF9zZWdtZW50X3Bsb3QgPSBmaWx0ZXIoZ2VuX2NvdW50LCBpbmZfcm91dGUgPT0gIkluZGV4IiB8IGluZl9yb3V0ZSA9PSAiQ29udHJvbCIpICU+JSAKICBmaWx0ZXIoRFBJID09ICJkMDIiIHwgRFBJID09ICJkMDQiIHwgRFBJID09ICJkMDYiIHwgRFBJID09ICJTdG9jayIpICU+JQpnZ3Bsb3QoLiAsIGFlcyh4ID0gZGlldCwgeSA9IHNudl9jb3VudCkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjIsIGFlcyhjb2xvciA9IGRpZXQpKSArCiAgZmFjZXRfZ3JpZCh+RFBJKSArCiAgeWxhYigiU05WIHJpY2huZXNzIHBlciBzYW1wbGUiKSArCiAgUGxvdFRoZW1lMSArCiAgRGlldGNvbFNjYWxlCnByaW50KGdlbl9jb3VudF9zZWdtZW50X3Bsb3QpCmdnc2F2ZSgiZ2VuX2NvdW50X3NlZ21lbnRfcGxvdC5wZGYiLGdlbl9jb3VudF9zZWdtZW50X3Bsb3QscGF0aD1zYXZlZGlyLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQpgYGAKVGVzdCBmb3Igc2lnbmlmaWNhbmNlCmBgYHtyfQpvID0gZmlsdGVyKGdlbl9jb3VudCwgaW5mX3JvdXRlID09ICJJbmRleCIgJiBEUEkgPT0gImQwNiIgJiBkaWV0ID09ICJPYmVzZSIpCmwgPSBmaWx0ZXIoZ2VuX2NvdW50LCBpbmZfcm91dGUgPT0gIkluZGV4IiAmIERQSSA9PSAiZDA2IiAmIGRpZXQgPT0gIkxlYW4iKQp0LnRlc3QobyRzbnZfY291bnQsbCRzbnZfY291bnQpCmBgYAoKTm9ybSBzbnZfY291bnQgYnkgdGl0ZXIKYGBge3J9CmF2Z190aXRlcl9kZiA9IHNlbGVjdChtZXRhLCBmZXJyZXRJRCwgRFBJLCBpbmZfcm91dGUsIGRpZXQsIHRpdGVyLCBsb2cxMF90aXRlcikgJT4lCiAgZmlsdGVyKCFpcy5uYSh0aXRlcikpICU+JQogIGRyb3BsZXZlbHMoKQphdmdfdGl0ZXJfZGYgPSBhdmdfdGl0ZXJfZGZbIWR1cGxpY2F0ZWQoYXZnX3RpdGVyX2RmKSwgXQogIApzZWdfY291bnRfdGl0ZXIgPSBtZXJnZShzZWdfY291bnQsIGF2Z190aXRlcl9kZiwgYnkgPSBjKCJmZXJyZXRJRCIsIkRQSSIsImRpZXQiLCJpbmZfcm91dGUiKSkKc2VnX2NvdW50X3RpdGVyJG5vcm1fc252ID0gc2VnX2NvdW50X3RpdGVyJHNudl9jb3VudCAvIHNlZ19jb3VudF90aXRlciRsb2cxMF90aXRlcgoKc2VnX2NvdW50X3RpdGVyMSA9IGZpbHRlcihzZWdfY291bnRfdGl0ZXIsIG5vcm1fc252ID09ICJOYU4iKQpzZWdfY291bnRfdGl0ZXIxJG5vcm1fc252ID0gMApzZWdfY291bnRfdGl0ZXIyID0gZmlsdGVyKHNlZ19jb3VudF90aXRlciwgbm9ybV9zbnYgIT0gIk5hTiIpCgpzZWdfY291bnRfdGl0ZXIgPSByYmluZChzZWdfY291bnRfdGl0ZXIxLHNlZ19jb3VudF90aXRlcjIpCmBgYAoKYGBge3J9CnNudl9jb3VudF9zZWdfdGl0ZXJfcGxvdCA9IGZpbHRlcihzZWdfY291bnRfdGl0ZXIsIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSAlPiUgCiAgZmlsdGVyKERQSSA9PSAiZDAyIiB8IERQSSA9PSAiZDA0IiB8IERQSSA9PSAiZDA2IikgJT4lCgpnZ3Bsb3QoLiAsIGFlcyh4ID0gc2VnbWVudCwgeSA9IG5vcm1fc252LCBjb2xvciA9IGRpZXQpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogICNnZW9tX3BvaW50KCkgKwogIGZhY2V0X2dyaWQofkRQSSkgKwogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQpwcmludChzbnZfY291bnRfc2VnX3RpdGVyX3Bsb3QpCmdnc2F2ZSgic252X2NvdW50X3NlZ190aXRlcl9wbG90LnBkZiIsIHNudl9jb3VudF9zZWdfdGl0ZXJfcGxvdCwgcGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gMTAsIGhlaWdodCA9IDUpCmBgYAoKVHJ5aW5nIHRvIGRvIGF2ZXJhZ2Ugc252IGNvdW50IHBlciBmZXJyZXQgd2l0aGluIGEgZGlldF9wYWlycyBncm91cApgYGB7cn0KI21pbm9ydmRmX3BhaXJzID0gbWVyZ2UobWlub3J2ZGYsIHBhaXJzLCBieSA9IGMoImZlcnJldElEIikpCgojZ3JvdXBfbGlzdF9wYWlycyA9IGMoJ2ZlcnJldElEJywiRFBJIiwiZGlldCIsImluZl9yb3V0ZSIsImNvaG9ydCIsJ3BhaXJfZGlldHMnKSAjIGNvdW50cyBhY3Jvc3MgZWFjaCBzZWdtZW50IAojcGFpcnNfY291bnQgPSBUYWxseUl0KG1pbm9ydmRmX3BhaXJzLCBncm91cF9saXN0X3BhaXJzLCAic252X2NvdW50IikKCiNwYWlyc19jb3VudCA9IG1lcmdlKHBhaXJzX2NvdW50LHJlc2VxX2dlbiwgYWxsID0gVFJVRSkKI3BhaXJzX2NvdW50ID0gcGFpcnNfY291bnRbIWR1cGxpY2F0ZWQocGFpcnNfY291bnQpLCBdCgojcGFpcnNfY291bnRfYXZnID0gZ3JvdXBfYnkocGFpcnNfY291bnQsIERQSSwgZGlldCwgaW5mX3JvdXRlLHBhaXJfZGlldHMpICU+JQojICBtdXRhdGUoYXZnU05WID0gbWVhbihzbnZfY291bnQpLCBzZFNOViA9IHNkKHNudl9jb3VudCkpCmBgYAoKYGBge3J9Cmdlbl9jb3VudF9wYWlycyA9IG1lcmdlKGdlbl9jb3VudCwgcGFpcnMsIGJ5ID0gYygiZmVycmV0SUQiKSkKCmdlbl9wYWlyc19wbG90ID0gZ2dwbG90KGdlbl9jb3VudF9wYWlycyAsIGFlcyh4PURQSSAsIHkgPSBzbnZfY291bnQsIGNvbG9yID0gZGlldCkpICsKICBnZW9tX3BvaW50KGFlcyhncm91cCA9IGRpZXQpLCBzaXplID0gMikgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBmZXJyZXRJRCkpICsKICAjZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGF2Z1NOViAtIHNkU05WLAogICMgICAgICAgICAgICAgICAgICB5bWF4ID0gYXZnU05WICsgc2RTTlYpKSArCiAgeWxhYigiQXZlcmFnZSBudW1iZXIgb2YgU05WcyBwZXIgc2FtcGxlIikgKwogIHhsYWIoIkRheXMgYWZ0ZXIgaW5mZWN0aW9uIikgKwogIGZhY2V0X2dyaWQocGFpcl9kaWV0c35pbmZfcm91dGUpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKcHJpbnQoZ2VuX3BhaXJzX3Bsb3QpCmdnc2F2ZSgiZ2VuX3BhaXJzX3Bsb3RfYWxsLnBkZiIsIGdlbl9wYWlyc19wbG90LCBwYXRoID0gc2F2ZWRpcikKYGBgCgpHZW5ldGljIGRpc3RhbmNlIG1lYXN1cmUKCmBgYHtyfQpkaXN0dmFycyA9IHJlYWQuY3N2KCIvVXNlcnMvbWFyaXNzYWtub2xsL0Rlc2t0b3AvR2l0SHViL09iZXNpdHkvTmV3RXh0cmFjdGlvbnMvSDlOMi92YXJmaWxlcy9IOU4yLlZhcmlhbnRQb3NpdGlvbnMuQWNyb3NzU2FtcGxlcy4wLjAxLjIwMC5jc3YiLCBoZWFkZXIgPSBUKQpkaXN0dmFycyA9IGRpc3R2YXJzWyFkdXBsaWNhdGVkKGRpc3R2YXJzKSwgXSAlPiUgZmlsdGVyKHNhbXBsZSAlaW4lIGdvb2RfbmFtZXMpCmBgYAoKYGBge3J9CmdkMiA9IHNlbGVjdChkaXN0dmFycyxzYW1wbGUsc2VnbWVudCxudHBvcyxudCxmcmVxKSAlPiUgZmlsdGVyKHNhbXBsZSAlaW4lIGdvb2RfbmFtZXMpICNNQVJJU1NBIENIRUNLIFRISVMgLSBXSFkgRE9OJ1QgVEhFIEdPT0QgTkFNRVMgTUFUQ0gKZ2QyJHNhbXBsZSA9IHBhc3RlMCgnZicsIGdkMiRzYW1wbGUpCgpnZDIgPSBnZDIgJT4lIGZpbHRlcihudCAhPSAiLSIpICU+JQogIGdyb3VwX2J5KHNhbXBsZSwgc2VnbWVudCkgJT4lCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IG50LCB2YWx1ZXNfZnJvbSA9IGZyZXEsIGlkX2NvbHMgPSBjKHNhbXBsZSwgc2VnbWVudCwgbnRwb3MpLCB2YWx1ZXNfZmlsbCA9IDApICU+JQogIGFycmFuZ2Uoc2VnbWVudCxudHBvcykKCmdkMiA9IGdkMlshZHVwbGljYXRlZChnZDIpLF0gJT4lIGRyb3BsZXZlbHMoKSAjIHJlbW92ZSBhbnkgZHVwcwoKZ2QyJHBvc2l0aW9ucyA9IHBhc3RlMChnZDIkc2VnbWVudCwnXycsIGdkMiRudHBvcykKcG9zaXRpb25zID0gYyhsZXZlbHMoZmFjdG9yKGdkMiRwb3NpdGlvbnMpKSkKCmdkMiA9IGZpbHRlcihnZDIsIHNhbXBsZSAhPSAiZjE0MTVfZDAyIikKYGBgCgpgYGB7cn0KZmlsdGVyKGdkMiwgcG9zaXRpb25zID09ICJIOU4yX1BCMl85ODQiKQpmaWx0ZXIoZGlzdHZhcnMsIG50cG9zID09ICI5ODQiKQpgYGAKCmBgYHtyfQpnZDIgPSBnZDIgJT4lIGdyb3VwX2J5KHNhbXBsZSkgJT4lCm11dGF0ZShzYW1wbGVfY291bnQgPSBuKCkpICU+JQp1bmdyb3VwKCkgJT4lIGZpbHRlcihzYW1wbGVfY291bnQgPT0gNjg2KSAlPiUgdW5pcXVlKCkKCmdkMiAlPiUgc2VsZWN0KHNhbXBsZV9jb3VudCxzYW1wbGUpICU+JSB1bmlxdWUoKSAlPiUgZ3JvdXBfYnkoc2FtcGxlX2NvdW50KSAlPiUgdGFsbHkoKSAjIHRyeWluZyB0byBkZXRlcm1pbmUgcG9zaXRpb25zIHRoYXQgcGFzc2VkIGN1dG9mZiAtPiBmaWd1cmUgb3V0IHdoeSB0aGlzIGlzbid0IGFsbCBvZiB0aGVtIChldmVudHVhbGx5KQojIEthdGUgdGhpbmtzIGl0IGlzIHB5dGhvbiBjb2RlIGluIGdlbmVyYXRpbmcgLmNzdiwgc3BlY2lmaWNhbGx5IHRoZSB0b3RhbGNvdW50IChtYWpvciBjdXRvZmYpIG5vdCBwYXNzaW5nIGEgdGhyZXNob2xkCgpzZXQxID0gdW5pcXVlKGZhY3RvcihnZDIkc2FtcGxlKSkgI2NoZWNrIHRvIG1ha2Ugc3VyZSBldmVyeXRoaW5nIGlzIHRoZSBzYW1lIHNpemUgdGhyb3VnaG91dAoKZGlzdF9wcmVwID0gYXMuZGF0YS5mcmFtZShnZDIpICU+JSBzZWxlY3QoLW50cG9zLCAtc2VnbWVudCwtc2FtcGxlX2NvdW50KSAlPiUgdW5pcXVlKCkKCmZvciAocG9zIGluIHBvc2l0aW9ucyl7CiAgCiAgZGlzdF9vcmlnID0gbWF0cml4KGRhdGEgPSAwLCBucm93ID0gbGVuZ3RoKHNldDEpICwgbmNvbCA9IGxlbmd0aChzZXQxKSkgIyBnZW5lcmF0ZSBlbXB0eSBtYXRyaXggdG8gYWRkIGRpc3QgbnVtYmVycyB0bwoKICByb3duYW1lcyhkaXN0X29yaWcpID0gc2V0MQogIGNvbG5hbWVzKGRpc3Rfb3JpZykgPSBzZXQxCiAgCiAgZDEgPSBkaXN0X3ByZXAgJT4lIGZpbHRlcihwb3NpdGlvbnMgPT0gcG9zKSAlPiUgdW5pcXVlKCkKICAKICByb3duYW1lcyhkMSkgPSBkMSRzYW1wbGUgIyBtYWtlIHJvd25hbWVzIHRoZSBzYW1wbGUgbmFtZXMKICBkMVssMV0gPSBOVUxMICMgcmVtb3ZlIHRoZSByb3cgbmFtZXMgY29sdW1ucyAod2hpY2ggaXMgdGhlIGZpcnN0IGNvbHVtbiBzZWxlY3RlZCkKICAKICBEX21hbiA9IGRpc3QoZDEsIG1ldGhvZD0ibWFuaGF0dGFuIikgIyBtYW5oYXR0YW4gZGlzdGFuY2UgPSBMMSBub3JtCiAgRF9tYW4gPSBhcy5tYXRyaXgoRF9tYW4pICNjaGFuZ2UgZGlzdCB0eXBlIHRvIG1hdHJpeAogIAogICMgY2hlY2sgdG8gbWFrZSBzdXJlIGRpc3Rfb3JpZyBhbmQgZGlzdF9ldWMgYXJlIGluIHNhbWUgb3JkZXIKICAjIGNoYW5nZSBvcmRlciBvZiBkaXN0X29yaWcgdG8gb3JkZXIgb2YgZGlzdF9ldWMKICBkaXN0X29yaWcgPSBkaXN0X29yaWdbcm93bmFtZXMoRF9tYW4pLCBdCiAgZGlzdF9vcmlnID0gZGlzdF9vcmlnWyxjb2xuYW1lcyhEX21hbildCiAgCiAgaWYoaWRlbnRpY2FsKGRpbW5hbWVzKGRpc3Rfb3JpZyksIGRpbW5hbWVzKERfbWFuKSkgPT0gVFJVRSl7CiAgICAKICAgICAgZGlzdF9tYW4gPC0gZGlzdF9vcmlnICsgRF9tYW4gI2FkZCB0byB0aGUgb3ZlcmFsbCBtYXRyaXgKICAgIAogIH1lbHNlewogICAgCiAgICBwcmludCgiZGltbmFtZXMgYXJlIG9mZiIpCiAgICAKICB9CiAgCn0KCmZvciAocG9zIGluIHBvc2l0aW9ucyl7CiAgCiAgZGlzdF9vcmlnID0gbWF0cml4KGRhdGEgPSAwLCBucm93ID0gbGVuZ3RoKHNldDEpICwgbmNvbCA9IGxlbmd0aChzZXQxKSkgIyBnZW5lcmF0ZSBlbXB0eSBtYXRyaXggdG8gYWRkIGRpc3QgbnVtYmVycyB0bwoKICByb3duYW1lcyhkaXN0X29yaWcpID0gc2V0MQogIGNvbG5hbWVzKGRpc3Rfb3JpZykgPSBzZXQxCiAgCiAgZDEgPSBkaXN0X3ByZXAgJT4lIGZpbHRlcihwb3NpdGlvbnMgPT0gcG9zKSAlPiUgdW5pcXVlKCkKICAKICByb3duYW1lcyhkMSkgPSBkMSRzYW1wbGUgIyBtYWtlIHJvd25hbWVzIHRoZSBzYW1wbGUgbmFtZXMKICBkMVssMV0gPSBOVUxMICMgcmVtb3ZlIHRoZSByb3cgbmFtZXMgY29sdW1ucyAod2hpY2ggaXMgdGhlIGZpcnN0IGNvbHVtbiBzZWxlY3RlZCkKICAKICBkMSA9IGQxW29yZGVyKHJvdy5uYW1lcyhkMSkpLF0gIyBvcmRlciB0aGUgcm93cwogIAogIERfZXVjID0gZGlzdChkMSwgbWV0aG9kPSJldWNsaWRlYW4iKSAjIGV1Y2xpZGVhbiBkaXNhdG5jZSA9IEwyIG5vcm0KICBEX2V1YyA9IGFzLm1hdHJpeChEX2V1YykgI2NoYW5nZSBkaXN0IHR5cGUgdG8gbWF0cml4CiAgCiAgIyBjaGVjayB0byBtYWtlIHN1cmUgZGlzdF9vcmlnIGFuZCBkaXN0X2V1YyBhcmUgaW4gc2FtZSBvcmRlcgogICMgY2hhbmdlIG9yZGVyIG9mIGRpc3Rfb3JpZyB0byBvcmRlciBvZiBkaXN0X2V1YwogIGRpc3Rfb3JpZyA9IGRpc3Rfb3JpZ1tyb3duYW1lcyhEX2V1YyksIF0KICBkaXN0X29yaWcgPSBkaXN0X29yaWdbLGNvbG5hbWVzKERfZXVjKV0KICAKICBpZihpZGVudGljYWwoZGltbmFtZXMoZGlzdF9vcmlnKSwgZGltbmFtZXMoRF9ldWMpKSA9PSBUUlVFKXsKICAgIAogICAgICBkaXN0X2V1YyA8LSBkaXN0X29yaWcgKyBEX2V1YyAjYWRkIHRvIHRoZSBvdmVyYWxsIG1hdHJpeAogICAgCiAgfWVsc2V7CiAgICAKICAgIHByaW50KCJkaW1uYW1lcyBhcmUgb2ZmIikKICAgIAogIH0KICAKfQoKCmBgYAoKYGBge3J9Cm1ldGEkbmFtZSA9IHBhc3RlMCgiZiIsbWV0YSRzYW1wbGUpCnJlZF9tZXRhID0gc2VsZWN0KG1ldGEsIG5hbWUsY29ob3J0LGZlcnJldElELERQSSxpbmZfcm91dGUsZGlldCkKCiMgTWFuaGF0dGFuIGRpc3RhbmNlcyAoTDEgbm9ybSkKbWFuX2RmID0gYXMuZGF0YS5mcmFtZShkaXN0X21hbikKbWFuX2RmJHNhbXBsZSA9IHJvd25hbWVzKG1hbl9kZikKCm1hbl9sb25nID0gbWFuX2RmICU+JQogIHBpdm90X2xvbmdlcighc2FtcGxlLCBuYW1lc190byA9IGMoImNvbXAiKSwgdmFsdWVzX3RvID0gImRpc3QiKQptYW5fbG9uZyA9IG1hbl9sb25nWyFkdXBsaWNhdGVkKG1hbl9sb25nKSwgXSAlPiUgZHJvcGxldmVscygpCgptYW5fbG9uZ19tID0gbWVyZ2UocmVkX21ldGEsIG1hbl9sb25nLCBieS54ID0gYygibmFtZSIpLCBieS55ID0gYygic2FtcGxlIikpCm1hbl9sb25nX20gPSBtYW5fbG9uZ19tWyFkdXBsaWNhdGVkKG1hbl9sb25nX20pLCBdICU+JSBkcm9wbGV2ZWxzKCkKCiMgRXVjbGlkaWFuIGRpc3RhbmNlcyAoTDIgbm9ybSkKZXVjX2RmID0gYXMuZGF0YS5mcmFtZShkaXN0X2V1YykKZXVjX2RmJHNhbXBsZSA9IHJvd25hbWVzKGV1Y19kZikKCmV1Y19sb25nID0gZXVjX2RmICU+JQogIHBpdm90X2xvbmdlcighc2FtcGxlLCBuYW1lc190byA9IGMoImNvbXAiKSwgdmFsdWVzX3RvID0gImRpc3QiKQpldWNfbG9uZyA9IGV1Y19sb25nWyFkdXBsaWNhdGVkKGV1Y19sb25nKSwgXSAlPiUgZHJvcGxldmVscygpCgpldWNfbG9uZ19tID0gbWVyZ2UocmVkX21ldGEsIGV1Y19sb25nLCBieS54ID0gYygibmFtZSIpLCBieS55ID0gYygic2FtcGxlIikpCmV1Y19sb25nX20gPSBldWNfbG9uZ19tWyFkdXBsaWNhdGVkKGV1Y19sb25nX20pLCBdICU+JSBkcm9wbGV2ZWxzKCkKYGBgCgpNZXJnZSBhZ2FpbiBzbyB3ZSBoYXZlIGluZm8gZm9yIGJvdGggc2FtcGxlcyBpbiBhIGNvbXBhcmlzb24KYGBge3J9Cm1hbl9sb25nID0gbWVyZ2UocmVkX21ldGEsIG1hbl9sb25nX20sIGJ5LnggPSBjKCJuYW1lIiksIGJ5LnkgPSBjKCJjb21wIikpCm1hbl9sb25nID0gbWFuX2xvbmdbIWR1cGxpY2F0ZWQobWFuX2xvbmcpLCBdICU+JSBkcm9wbGV2ZWxzKCkKCmV1Y19sb25nID0gbWVyZ2UocmVkX21ldGEsIGV1Y19sb25nX20sIGJ5LnggPSBjKCJuYW1lIiksIGJ5LnkgPSBjKCJjb21wIikpCmV1Y19sb25nID0gZXVjX2xvbmdbIWR1cGxpY2F0ZWQoZXVjX2xvbmcpLCBdICU+JSBkcm9wbGV2ZWxzKCkKYGBgCgpgYGB7cn0KTDFfc3RvY2tfaW5kZXggPSBnZ3Bsb3QoZmlsdGVyKG1hbl9sb25nLCBpbmZfcm91dGUueCA9PSAiQ29udHJvbCIgJiAKICAgICAgICAgICAgICAgIGluZl9yb3V0ZS55ID09ICJJbmRleCIgJgogICAgICAgICAgICAgICAgY29ob3J0LnggPT0gY29ob3J0LnkpKSArCiAgZ2VvbV9ib3hwbG90KGFlcyh4ID0gZGlldC55LCB5ID0gZGlzdCksIG91dGxpZXIuc2hhcGUgPSAgTkEsIHdpZHRoID0gMC41KSArCiAgZ2VvbV9qaXR0ZXIoYWVzKHggPSBkaWV0LnksIHkgPSBkaXN0LCBncm91cCA9IGRpZXQueSwgY29sb3IgPSBkaWV0LnkpLCB3aWR0aCA9IDAuMSkgKwogIGZhY2V0X2dyaWQofkRQSS55LHNjYWxlcyA9ICdmcmVlJywgc3BhY2UgPSdmcmVlJykgKwogIGdndGl0bGUoIkwxLW5vcm0gYmV0d2VlbiBpbmRleCBzYW1wbGVzIGFuZCBzdG9jayIpICsKICB4bGFiKCJEaWV0IG9mIGluZGV4IGZlcnJldCIpICsKICB5bGFiKCJMMS1ub3JtIChNYW4uIGRpc3RhbmNlKSIpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKcHJpbnQoTDFfc3RvY2tfaW5kZXgpCmdnc2F2ZSgiTDFfc3RvY2tfaW5kZXgucGRmIixMMV9zdG9ja19pbmRleCxwYXRoID0gc2F2ZWRpcikKCkwyX3N0b2NrX2luZGV4ID0gZ2dwbG90KGZpbHRlcihldWNfbG9uZywgaW5mX3JvdXRlLnggPT0gIkNvbnRyb2wiICYgCiAgICAgICAgICAgICAgICBpbmZfcm91dGUueSA9PSAiSW5kZXgiICYKICAgICAgICAgICAgICAgIGNvaG9ydC54ID09IGNvaG9ydC55KSkgKwogIGdlb21fYm94cGxvdChhZXMoeCA9IGRpZXQueSwgeSA9IGRpc3QpLCBvdXRsaWVyLnNoYXBlID0gIE5BLCB3aWR0aCA9IDAuNSkgKwogIGdlb21faml0dGVyKGFlcyh4ID0gZGlldC55LCB5ID0gZGlzdCwgZ3JvdXAgPSBkaWV0LnksIGNvbG9yID0gZGlldC55KSwgd2lkdGggPSAwLjEpICsKICBmYWNldF9ncmlkKH5EUEkueSxzY2FsZXMgPSAnZnJlZScsIHNwYWNlID0nZnJlZScpICsKICBnZ3RpdGxlKCJMMS1ub3JtIGJldHdlZW4gaW5kZXggc2FtcGxlcyBhbmQgc3RvY2siKSArCiAgeGxhYigiRGlldCBvZiBpbmRleCBmZXJyZXQiKSArCiAgeWxhYigiTDItbm9ybSAoRXVjLiBkaXN0YW5jZSkiKSArCiAgUGxvdFRoZW1lMSArCiAgRGlldGNvbFNjYWxlCnByaW50KEwyX3N0b2NrX2luZGV4KQpnZ3NhdmUoIkwyX3N0b2NrX2luZGV4LnBkZiIsTDJfc3RvY2tfaW5kZXgscGF0aCA9IHNhdmVkaXIpCmBgYAoKYGBge3J9CiMgVCB0ZXN0cwpvYl9kMDYgPSBmaWx0ZXIobWFuX2xvbmcsIGluZl9yb3V0ZS54ID09ICJDb250cm9sIiAmIGluZl9yb3V0ZS55ID09ICJJbmRleCIgJgogICAgICAgICAgICAgICAgICBjb2hvcnQueCA9PSBjb2hvcnQueSAmCiAgICAgICAgICAgICAgICAgIGRpZXQueSA9PSAiT2Jlc2UiICYgRFBJLnkgPT0gImQwNiIpCmxuX2QwNiA9IGZpbHRlcihtYW5fbG9uZywgaW5mX3JvdXRlLnggPT0gIkNvbnRyb2wiICYgaW5mX3JvdXRlLnkgPT0gIkluZGV4IiAmCiAgICAgICAgICAgICAgICAgIGNvaG9ydC54ID09IGNvaG9ydC55ICYKICAgICAgICAgICAgICAgICAgZGlldC55ID09ICJMZWFuIiAmIERQSS55ID09ICJkMDYiKQp0LnRlc3Qob2JfZDA2JGRpc3QsbG5fZDA2JGRpc3QpCmBgYAoKYGBge3J9Cm1hbl9sb25nX3BhaXIgPSBtZXJnZShtYW5fbG9uZywgcGFpcnMsIGJ5LnggPSBjKCJmZXJyZXRJRC54IiksIGJ5LnkgPSBjKCJmZXJyZXRJRCIpKQptYW5fbG9uZ19wID0gbWVyZ2UobWFuX2xvbmdfcGFpciwgcGFpcnMsIGJ5LnggPSBjKCJmZXJyZXRJRC55IiksIGJ5LnkgPSBjKCJmZXJyZXRJRCIpKQpgYGAKCmBgYHtyfQpzdG9ja19pbmRleCA9IGZpbHRlcihtYW5fbG9uZywgaW5mX3JvdXRlLnggPT0gIkNvbnRyb2wiICYgaW5mX3JvdXRlLnkgPT0gIkluZGV4IiAmIGNvaG9ydC54ID09IGNvaG9ydC55KSAlPiUKICBtdXRhdGUoY2F0ID0gIlN0b2NrIC0+IEluZGV4IiwKICAgICAgICAgZ3JvdXAgPSAiU3RvY2siKSAlPiUKICBtdXRhdGUocGFpcl9udW1iZXJzLnggPSBOQSwKICAgICAgICAgcGFpcl9kaWV0cy54ID0gTkEsCiAgICAgICAgIHBhaXJfbnVtYmVycy55ID0gTkEsCiAgICAgICAgIHBhaXJfZGlldHMueSA9IE5BKSAlPiUKICBzZWxlY3QoLWMoImdyb3VwIikpCmluZGV4X2NvbnRhY3RfcGFpcnMgPSBmaWx0ZXIobWFuX2xvbmdfcCwgaW5mX3JvdXRlLnggPT0gIkluZGV4IiAmIGluZl9yb3V0ZS55ID09ICJDb250YWN0IiAmIHBhaXJfbnVtYmVycy54ID09IHBhaXJfbnVtYmVycy55KSAlPiUKICBtdXRhdGUoY2F0ID0gIkluZGV4IC0+IENvbnRhY3QgKFBhaXJzKSIpCiMgMTAgTE4gLT4gTE4sIDIgTE4gLT4gT0IsIDI2IE9CIC0+IE9CCmluZGV4X2NvbnRhY3Rfbm90cGFpcnMgPSBmaWx0ZXIobWFuX2xvbmdfcCwgaW5mX3JvdXRlLnggPT0gIkluZGV4IiAmIGluZl9yb3V0ZS55ID09ICJDb250YWN0IiAmIHBhaXJfbnVtYmVycy54ICE9IHBhaXJfbnVtYmVycy55KSAlPiUKICBtdXRhdGUoY2F0ID0gIkluZGV4IC0+IENvbnRhY3QgKE5vdCBQYWlycykiKQoKbWFuX2NvbXBzID0gcmJpbmQoc3RvY2tfaW5kZXgsIGluZGV4X2NvbnRhY3RfcGFpcnMsIGluZGV4X2NvbnRhY3Rfbm90cGFpcnMpCm1hbl9jb21wcyRjYXQgPSBmYWN0b3IobWFuX2NvbXBzJGNhdCwgbGV2ZWxzID0gYygiU3RvY2sgLT4gSW5kZXgiLCJJbmRleCAtPiBDb250YWN0IChQYWlycykiLCJJbmRleCAtPiBDb250YWN0IChOb3QgUGFpcnMpIikpCgpnZ3Bsb3QobWFuX2NvbXBzKSArCiAgZ2VvbV9ib3hwbG90KGFlcyh4ID0gY2F0LCB5ID0gZGlzdCwgY29sb3IgPSBkaWV0LnkpLCBvdXRsaWVyLnNoYXBlID0gIE5BLCB3aWR0aCA9IDAuNSkgKwojICBnZW9tX2ppdHRlcihhZXMoeCA9IGNhdCwgeSA9IGRpc3QsIGdyb3VwID0gZGlldC55LCBjb2xvciA9IGRpZXQueSksIHdpZHRoID0gMC4xKSArCiAgZ2d0aXRsZSgiTDEtbm9ybSBiZXR3ZWVuIGluZGV4IHNhbXBsZXMgYW5kIHN0b2NrIikgKwogIHhsYWIoIkNvbXBhcmlzb24iKSArCiAgeWxhYigiTDEtbm9ybSAoTWFuLiBkaXN0YW5jZSkiKSArCiAgUGxvdFRoZW1lMSArCiAgRGlldGNvbFNjYWxlCiMgdGhlIG91dGxpZXJzIGFyZSBhbGwgY29tcGFyaXNvbnMgdG8gMTQxNV9kMDIgd2hpY2ggaXMgd2VpcmQKYGBgCgpgYGB7cn0KTE5fTE4gPSBmaWx0ZXIobWFuX2xvbmdfcCwgaW5mX3JvdXRlLnggPT0gIkluZGV4IiAmIGluZl9yb3V0ZS55ID09ICJDb250YWN0IiAmIAogICAgICAgICAgICAgICAgIHBhaXJfbnVtYmVycy54ID09IHBhaXJfbnVtYmVycy55ICYgcGFpcl9kaWV0cy54ID09ICJMTj5MTiIpICU+JQogIG11dGF0ZShjYXQgPSAiTGVhbiAtPiBMZWFuIFBhaXJzIikKCk9CX09CID0gZmlsdGVyKG1hbl9sb25nX3AsIGluZl9yb3V0ZS54ID09ICJJbmRleCIgJiBpbmZfcm91dGUueSA9PSAiQ29udGFjdCIgJiAKICAgICAgICAgICAgICAgICBwYWlyX251bWJlcnMueCA9PSBwYWlyX251bWJlcnMueSAmIHBhaXJfZGlldHMueCA9PSAiT0I+T0IiKSAlPiUKICBtdXRhdGUoY2F0ID0gIk9iZXNlIC0+IE9iZXNlIFBhaXJzIikKCm1hbl9jb21wczIgPSByYmluZChzdG9ja19pbmRleCwgTE5fTE4sIE9CX09CLCBpbmRleF9jb250YWN0X25vdHBhaXJzKQptYW5fY29tcHMyJGNhdCA9IGZhY3RvcihtYW5fY29tcHMyJGNhdCwgbGV2ZWxzID0gYygiU3RvY2sgLT4gSW5kZXgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxlYW4gLT4gTGVhbiBQYWlycyIsIk9iZXNlIC0+IE9iZXNlIFBhaXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmRleCAtPiBDb250YWN0IChOb3QgUGFpcnMpIikpCgpNYW5fcGxvdDIgPSBnZ3Bsb3QobWFuX2NvbXBzMikgKwogIGdlb21fYm94cGxvdChhZXMoeCA9IGNhdCwgeSA9IGRpc3QsIGNvbG9yID0gZGlldC55KSwgb3V0bGllci5zaGFwZSA9ICBOQSwgd2lkdGggPSAwLjUpICsKIyAgZ2VvbV9qaXR0ZXIoYWVzKHggPSBjYXQsIHkgPSBkaXN0LCBncm91cCA9IGRpZXQueSwgY29sb3IgPSBkaWV0LnkpLCB3aWR0aCA9IDAuMSkgKwogIGdndGl0bGUoIkwxLW5vcm0gYmV0d2VlbiBpbmRleCBzYW1wbGVzIGFuZCBzdG9jayIpICsKICB4bGFiKCJDb21wYXJpc29uIikgKwogIHlsYWIoIkwxLW5vcm0gKE1hbi4gZGlzdGFuY2UpIikgKwogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQpwcmludChNYW5fcGxvdDIpCmdnc2F2ZSgiTWFuX3Bsb3QyLnBkZiIsIE1hbl9wbG90Miwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSwgcGF0aCA9IHNhdmVkaXIpCmBgYAoKYGBge3J9CmdncGxvdChmaWx0ZXIobWFuX2xvbmcsIGluZl9yb3V0ZS54ID09ICJJbmRleCIgJgogICAgICAgICAgICAgICAgaW5mX3JvdXRlLnkgPT0gIkNvbnRhY3QiICYKICAgICAgICAgICAgICAgIHBhaXJfbnVtYmVycy54ID09IHBhaXJfbnVtYmVycy55KSkgKwogIGdlb21fYm94cGxvdChhZXMoeCA9IHBhaXJfbnVtYmVyLngsIHkgPSBkaXN0KSwgb3V0bGllci5zaGFwZSA9ICBOQSwgd2lkdGggPSAwLjUpICsKICBnZW9tX2ppdHRlcihhZXMoeCA9IGRpZXQueSwgeSA9IGRpc3QsIGdyb3VwID0gZGlldC55LCBjb2xvciA9IGRpZXQueCksIHdpZHRoID0gMC4xKSArCiAgI2ZhY2V0X2dyaWQofkRQSS55LHNjYWxlcyA9ICdmcmVlJywgc3BhY2UgPSdmcmVlJykgKwogIGdndGl0bGUoIkwxLW5vcm0gYmV0d2VlbiBpbmRleCBzYW1wbGVzIGFuZCBldmVyeXRoaW5nIGJ1dCB0aGVpciBjb250YWN0cyIpICsKICB4bGFiKCJEaWV0IG9mIGNvbnRhY3QgZmVycmV0IikgKwogIHlsYWIoIkwxLW5vcm0gKE1hbi4gZGlzdGFuY2UpIikgKwogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQpgYGAKClN0b2NrIHRvIEluZGV4IERheSAyIGNvbXBhcmlzb25zIChTdG9jayAtPiBMZWFuLCBTdG9jayAtPiBPYmVzZSkKYGBge3J9CmdncGxvdChmaWx0ZXIoZGlzdF9sb25nX20sIGNvaG9ydCA9PSAiVzE3IiwgY29tcCA9PSAiZlcxN19ISzEwNzMiLCBpbmZfcm91dGUgPT0gIkluZGV4IiwgRFBJID09ICJkMDIiKSwgCiAgICAgICBhZXMoeCA9IGRpZXQsIHkgPSBkaXN0KSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMSkgKwogIFBsb3RUaGVtZTEKIyBoYWQgdG8gZmlsdGVyIGJ5IGNvbXAgc28gdGhlIGluZGl2aWR1YWwgc2FtcGxlcyB3b3VsZCBrZWVwIHRoZWlyIG1ldGFkYXRhCgpnZ3Bsb3QoZmlsdGVyKGRpc3RfbG9uZ19tLCBjb2hvcnQgPT0gIkYxNyIsIGNvbXAgPT0gImZGMTdfSEsxMDczIiwgaW5mX3JvdXRlID09ICJJbmRleCIsIERQSSA9PSAiZDAyIiksIAogICAgICAgYWVzKHggPSBkaWV0LCB5ID0gZGlzdCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjEpICsKICBQbG90VGhlbWUxCgpnZ3Bsb3QoZmlsdGVyKGRpc3RfbG9uZ19tLCBjb2hvcnQgPT0gIlNtMTgiLCBjb21wID09ICJmU20xOF9ISzEwNzMiLCBpbmZfcm91dGUgPT0gIkluZGV4IiwgRFBJID09ICJkMDIiKSwgCiAgICAgICBhZXMoeCA9IGRpZXQsIHkgPSBkaXN0KSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMSkgKwogIFBsb3RUaGVtZTEKCmdncGxvdChmaWx0ZXIoZGlzdF9sb25nX20sIGNvaG9ydCA9PSAiU3AyMCIsIGNvbXAgPT0gImZTcDIwX0hLMTA3MyIsIGluZl9yb3V0ZSA9PSAiSW5kZXgiLCBEUEkgPT0gImQwMiIpLCAKICAgICAgIGFlcyh4ID0gZGlldCwgeSA9IGRpc3QpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4xKSArCiAgUGxvdFRoZW1lMQojIG5vIHNhbXBsZXMgZnJvbSB0aGlzIGNvaG9ydCBmb3VuZAoKI1NwMTkgc2FtcGxlcyBhcmUgZ29vZCwgdGhlIHN0b2NrIGlzIG1pc3NpbmcgLT4gbm90IGluIGdvb2Qgc2FtcGxlcwpgYGAKI2NvbXBhcmUgc3RvY2sgLT4gaW5kZXggb3ZlciBEUEkgKGV4cGVjdGF0aW9uIGlzIG1vcmUgZGlzdGFudCBvdmVyIHRpbWUpCmBgYHtyfQpnZ3Bsb3QoZmlsdGVyKGRpc3RfbG9uZ19tLCBjb2hvcnQgPT0gIlcxNyIsIGNvbXAgPT0gImZXMTdfSEsxMDczIiwgaW5mX3JvdXRlID09ICJJbmRleCIpLCAKICAgICAgIGFlcyh4ID0gRFBJLCB5ID0gZGlzdCkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIod2lkdGggPSAwLjEsIGFlcyhjb2xvciA9IGRpZXQpKSArCiAgUGxvdFRoZW1lMQoKZ2dwbG90KGZpbHRlcihkaXN0X2xvbmdfbSwgY29ob3J0ID09ICJGMTciLCBjb21wID09ICJmRjE3X0hLMTA3MyIsIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSwgCiAgICAgICBhZXMoeCA9IERQSSwgeSA9IGRpc3QpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4xLCBhZXMoY29sb3IgPSBkaWV0KSkgKwogIFBsb3RUaGVtZTEKCmdncGxvdChmaWx0ZXIoZGlzdF9sb25nX20sIGNvaG9ydCA9PSAiU20xOCIsIGNvbXAgPT0gImZTbTE4X0hLMTA3MyIsIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSwgCiAgICAgICBhZXMoeCA9IERQSSwgeSA9IGRpc3QpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4xLCBhZXMoY29sb3IgPSBkaWV0KSkgKwogIFBsb3RUaGVtZTEKYGBgCgpBZGQgdHJhbnNtaXNzaW9uIGRhdGEKI2NvbXBhcmUgbGVhbiAtPiBsZWFuIHRyYW5zbWlzc2lvbgojY29tcGFyZSBkMDIgaW5kZXggLT4gYWxsIGNvbnRhY3QgdGltZSBwb2ludHMgKGRvIHRoZSBjb250YWN0cyBkaXZlcmdlIGZyb20gdGhlaXIgZG9ub3JzIG92ZXIgdGltZSkKI2NvbXBhcmUgbGFzdCB0aW1lIHBvaW50IGluZGV4IC0gbGFzdCB0aW1lIHBvaW50IGNvbnRhY3QKYGBge3J9CmdncGxvdChmaWx0ZXIoZGlzdF9sb25nX3BhaXJzLCBjb2hvcnQueCA9PSAiU20xOCIgJiBjb2hvcnQueSA9PSAiU20xOCIgJiBwYWlyX251bWJlcnMueCA9PSBwYWlyX251bWJlcnMueSwgZGlzdCA+IDApLCAKICAgICAgIGFlcyh4ID0gaW5mX3JvdXRlLngsIHkgPSBkaXN0KSkgKwogIGdlb21fYm94cGxvdCgpICsKICBnZW9tX2ppdHRlcih3aWR0aCA9IDAuMSwgYWVzKGNvbG9yID0gZGlldC54KSkgKwogIGZhY2V0X2dyaWQofnBhaXJfZGlldHMueCkgKwogIFBsb3RUaGVtZTEKYGBgCgoKRG8gdGhlIG51bWJlciBvZiB2YXJpYW50cyBjb3JyZWxhdGUgd2l0aCBDdD8KYGBge3J9Cm1ldGFfc21hbGwgPSBzZWxlY3QobWV0YSwiZmVycmV0SUQiLCJEUEkiLCJkaWV0IiwiaW5mX3JvdXRlIiwiY29ob3J0IiwiQ3RfTWdlbmUiKQp2YXJjb3VudCA9IG1lcmdlKGdlbl9jb3VudF9hdmcsIG1ldGFfc21hbGwsIGJ5ID0gYygiZmVycmV0SUQiLCJEUEkiLCJkaWV0IiwiaW5mX3JvdXRlIiwiY29ob3J0IikpCgpnZ3Bsb3QodmFyY291bnQsIGFlcyh4ID0gQ3RfTWdlbmUsIHkgPSBzbnZfY291bnQsIGNvbG9yID0gZGlldCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJnbG0iKSArCiAgI3lsaW0oMjAsMzApICsKICBmYWNldF9ncmlkKH5pbmZfcm91dGUpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKIyB3aWxsIGdldCBhIHdhcm5pbmcgd2hlbiBOQXMgYXJlIHJlbW92ZWQKCkNUX1NOVmNvdW50X3Bsb3QgPSBnZ3Bsb3QoZmlsdGVyKHZhcmNvdW50LCBpbmZfcm91dGUgIT0gIkNvbnRyb2wiKSwgYWVzKHggPSBDdF9NZ2VuZSwgeSA9IHNudl9jb3VudCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJnbG0iKSArCiAgI3lsaW0oMjAsMzApICsKICBmYWNldF9ncmlkKH5pbmZfcm91dGUpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKcHJpbnQoQ1RfU05WY291bnRfcGxvdCkKZ2dzYXZlKCJDVF9TTlZjb3VudF9wbG90LnBkZiIsQ1RfU05WY291bnRfcGxvdCxwYXRoID0gc2F2ZWRpciwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSkKYGBgCgpgYGB7cn0KI1NOVnNfVGl0ZXIgPSBnZ3Bsb3QoZ2VuX2NvdW50LCBhZXMoeCA9IGxvZzEwX3RpdGVyLCB5ID0gc252X2NvdW50LCBjb2xvciA9IGRpZXQpKSArCiMgIGdlb21fcG9pbnQoYWVzKHNoYXBlID0gRFBJKSkgKwojICBnZW9tX3Ntb290aChtZXRob2QgPSAiZ2xtIikgKwojICBQbG90VGhlbWUxICsKIyAgRGlldGNvbFNjYWxlICsKIyAgeGxpbSgwLDcpICsKIyAgZmFjZXRfZ3JpZCh+aW5mX3JvdXRlKQojcHJpbnQoU05Wc19UaXRlcikKI2dnc2F2ZSgiU05Wc19UaXRlci5wZGYiLFNOVnNfVGl0ZXIscGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gNSkKI2dnc2F2ZSgiU05Wc19UaXRlci5wbmciLFNOVnNfVGl0ZXIscGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gNSkKCiMgVGhlcmUgYXJlIDE2IHBvaW50cyBpbiB0aGUgaW5kZXggZmVycmV0cyB3aXRoIExvZ1RpdGVyIDwgMyBpbiBJbmRleCBmZXJyZXRzIC0+IDIgc2FtcGxlcyAody8gOCBzZWdtZW50cykKIyBBcmUgdGhlc2Ugb3V0bGllcnMgdGhhdCBhIHNrZXdpbmcgdGhlIGRhdGE/CgojUG9zc091dGxpZXJzID0gZmlsdGVyKHZhcl90aXRlcnMsIGluZl9yb3V0ZSA9PSAiSW5kZXgiICYgZGlldCA9PSAiTGVhbiIgJiBMb2dUaXRlciA8IDMpCiNvdXRsaWVyU2FtcHMgPSBsZXZlbHMoZmFjdG9yKFBvc3NPdXRsaWVycyRTYW1wbGUpKQoKI3Zhcl90aXRlcnNfTm9PdXQgPSB2YXJfdGl0ZXJzICU+JSBmaWx0ZXIoIShTYW1wbGUgJWluJSBvdXRsaWVyU2FtcHMpKQoKI1NOVnNfVGl0ZXJfTm9PdXQgPSBnZ3Bsb3QodmFyX3RpdGVyc19Ob091dCwgYWVzKHggPSBMb2dUaXRlciwgeSA9IHNudl9jb3VudCwgY29sb3IgPSBkaWV0KSkgKwojICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9IERQSSkpICsKIyAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImdsbSIpICsKIyAgUGxvdFRoZW1lMSArCiMgIERpZXRjb2xTY2FsZSArCiMgIHhsaW0oMCw3KSArCiMgIGZhY2V0X2dyaWQofmluZl9yb3V0ZSkKI3ByaW50KFNOVnNfVGl0ZXJfTm9PdXQpCgojIE5Wc19UaXRlcl9Ob0RpZXQgPSBnZ3Bsb3QodmFyX3RpdGVycywgYWVzKHggPSBMb2dUaXRlciwgeSA9IHNudl9jb3VudCkpICsKIyAgZ2VvbV9wb2ludChhZXMoc2hhcGUgPSBEUEkpKSArCiMgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJnbG0iKSArCiMgIFBsb3RUaGVtZTEgKwojICBEaWV0Y29sU2NhbGUgKwojICB4bGltKDAsNykgKwojICBmYWNldF9ncmlkKH5pbmZfcm91dGUpCiNwcmludChTTlZzX1RpdGVyX05vRGlldCkKYGBgCgpgYGB7cn0KI21ldGFfc21hbGxlciA9IHNlbGVjdChtZXRhX3NtYWxsLGMoZmVycmV0SUQsIERQSSwgZGlldCwgaW5mX3JvdXRlKSkKI21ldGFfc21hbGxlciA9IG1ldGFfc21hbGxlclshZHVwbGljYXRlZChtZXRhX3NtYWxsZXIpLCBdCgojdGl0ZXJzX0g5X21ldGEgPSBtZXJnZSh0aXRlcnNfSDksIG1ldGFfc21hbGxlciwgYnkgPSBjKCJmZXJyZXRJRCIsICJEUEkiLCJkaWV0IiwiaW5mX3JvdXRlIikpCiN0aXRlcnNfSDlfbWV0YSA9IHRpdGVyc19IOV9tZXRhWyFkdXBsaWNhdGVkKHRpdGVyc19IOV9tZXRhKSwgXQoKI3RpdGVyc19IOV9tZXRhID0gdGl0ZXJzX0g5X21ldGFbIWR1cGxpY2F0ZWQodGl0ZXJzX0g5X21ldGEpLCBdCiN0aXRlcnNfSDlfbWV0YSRUaXRlcltpcy5uYSh0aXRlcnNfSDlfbWV0YSRUaXRlcildID0gMAojdGl0ZXJzX0g5X21ldGEgPSBmaWx0ZXIodGl0ZXJzX0g5X21ldGEsIFRpdGVyID4gMCkKCiNBdmdUaXRlcnMgPSBncm91cF9ieSh0aXRlcnNfSDlfbWV0YSwgZGlldCwgaW5mX3JvdXRlLERQSSkgJT4lCiMgIG11dGF0ZShMb2dUaXRlciA9IGxvZzEwKFRpdGVyKSkgJT4lIAojICBtdXRhdGUoYXZnVGl0ZXIgPSBtZWFuKExvZ1RpdGVyKSwgc2RUaXRlciA9IHNkKExvZ1RpdGVyKSkKI0F2Z1RpdGVycyRpbmZfcm91dGUgPSBmYWN0b3IoQXZnVGl0ZXJzJGluZl9yb3V0ZSwgbGV2ZWxzID0gYygiSW5kZXgiLCJDb250YWN0IikpCgojVGl0ZXJQbG90ID0gZ2dwbG90KEF2Z1RpdGVycywgYWVzKHggPSBEUEksIHkgPSBhdmdUaXRlciwgY29sb3IgPSBkaWV0KSkgKwojICBnZW9tX3BvaW50KCkgKwojICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gZGlldCkpICsKIyAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGF2Z1RpdGVyIC0gc2RUaXRlciwKIyAgICAgICAgICAgICAgICAgICAgeW1heCA9IGF2Z1RpdGVyICsgc2RUaXRlcikpICsKIyAgeWxpbSgwLDcpICsKIyAgZmFjZXRfZ3JpZCh+aW5mX3JvdXRlKSArCiMgIERpZXRjb2xTY2FsZSArCiMgIFBsb3RUaGVtZTEKI3ByaW50KFRpdGVyUGxvdCkKI2dnc2F2ZSgiVGl0ZXJQbG90LnBuZyIsIFRpdGVyUGxvdCwgd2lkdGggPSA3LCBoZWlnaHQgPSA1LCBwYXRoID0gc2F2ZWRpcikKCiN0aXRlcnNfSDlfbWV0YSRpbmZfcm91dGUgPSBmYWN0b3IodGl0ZXJzX0g5X21ldGEkaW5mX3JvdXRlLCBsZXZlbHMgPSBjKCJJbmRleCIsIkNvbnRhY3QiKSkKCiNBbGxUaXRlcnNQbG90ID0gZ2dwbG90KHRpdGVyc19IOV9tZXRhLCBhZXMoeCA9IERQSSwgeSA9IGxvZzEwKFRpdGVyKSwgY29sb3IgPSBhcy5jaGFyYWN0ZXIoZmVycmV0SUQpKSkgKwojICBnZW9tX3BvaW50KHNpemUgPSAzKSArCiMgIGdlb21fbGluZShhZXMoZ3JvdXAgPSBmZXJyZXRJRCksIHNpemUgPSAxLjUpICsKIyAgeWxpbSgwLDcpICsKIyAgZmFjZXRfZ3JpZChkaWV0fmluZl9yb3V0ZSkgKwojICBQbG90VGhlbWUxCiNwcmludChBbGxUaXRlcnNQbG90KQojZ2dzYXZlKCJBbGxUaXRlcnNQbG90LnBuZyIsIEFsbFRpdGVyc1Bsb3QsIHdpZHRoID0gMTQsIGhlaWdodCA9IDcsIHBhdGggPSBzYXZlZGlyKQpgYGAKCmROZFMgYW5hbHlzaXMKYGBge3J9CiMgYnkgZmVycmV0CmROZFNfZmVycmV0ID0gbWlub3J2ZGYgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZmVycmV0SUQsRFBJLGRpZXQsaW5mX3JvdXRlKSAlPiUgCiAgY291bnQobm9uc3luKQoKZE5kU19mZXJyZXQgPSBwaXZvdF93aWRlcihkTmRTX2ZlcnJldCxuYW1lc19mcm9tID0gbm9uc3luLCB2YWx1ZXNfZnJvbSA9IG4pCmROZFNfZmVycmV0ID0gc2VsZWN0KGROZFNfZmVycmV0LCBmZXJyZXRJRCxEUEksbm9uc3luLHN5bikKZE5kU19mZXJyZXQkZE5kUyA9IHBhc3RlMChkTmRTX2ZlcnJldCRub25zeW4gLyBkTmRTX2ZlcnJldCRzeW4pCmROZFNfZmVycmV0JGROZFMgPSBhcy5udW1lcmljKGROZFNfZmVycmV0JGROZFMpCgpkTmRTX2ZlcnJldCA9IGZpbHRlcihkTmRTX2ZlcnJldCwgaW5mX3JvdXRlID09ICJJbmRleCIgfCBpbmZfcm91dGUgPT0gIkNvbnRhY3QiKQoKZE5kU19mZXJyZXRfcGxvdCA9IGdncGxvdChkTmRTX2ZlcnJldCwgYWVzKHggPSBEUEksIHkgPSBkTmRTLCBjb2xvciA9IGZlcnJldElEKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGZlcnJldElEKSkgKwogIGZhY2V0X2dyaWQofmRpZXQraW5mX3JvdXRlKSArCiAgUGxvdFRoZW1lMQpwcmludChkTmRTX2ZlcnJldF9wbG90KQpnZ3NhdmUoImROZFNfZmVycmV0LnBkZiIsIGROZFNfZmVycmV0X3Bsb3QsIHBhdGggPSBzYXZlZGlyKQpnZ3NhdmUoImROZFNfZmVycmV0LnBuZyIsIGROZFNfZmVycmV0X3Bsb3QsIHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQpgYGAKCmBgYHtyfQojIGJ5IGZlcnJldCBhbmQgZ2VuZQojZE5kU19mZXJyZXRfZ2VuZSA9IG1pbm9ydmRmICU+JSAKIyAgdW5ncm91cCgpICU+JSAKIyAgZ3JvdXBfYnkoZmVycmV0SUQsRFBJLGRpZXQsaW5mX3JvdXRlLHNlZ21lbnQpICU+JSAKIyAgY291bnQobm9uc3luKQoKI2ROZFNfZmVycmV0X2dlbmUgPSBwaXZvdF93aWRlcihkTmRTX2ZlcnJldF9nZW5lLG5hbWVzX2Zyb20gPSBub25zeW4sIHZhbHVlc19mcm9tID0gbikKI2ROZFNfZmVycmV0X2dlbmUgPSBzZWxlY3QoZE5kU19mZXJyZXRfZ2VuZSwgZmVycmV0SUQsRFBJLG5vbnN5bixzeW4pCiNkTmRTX2ZlcnJldF9nZW5lJGROZFMgPSBwYXN0ZTAoZE5kU19mZXJyZXRfZ2VuZSRub25zeW4gLyBkTmRTX2ZlcnJldF9nZW5lJHN5bikKI2ROZFNfZmVycmV0X2dlbmUkZE5kUyA9IGFzLm51bWVyaWMoZE5kU19mZXJyZXRfZ2VuZSRkTmRTKQoKI2ROZFNfZmVycmV0X2dlbmVfcGxvdCA9IGdncGxvdChkTmRTX2ZlcnJldF9nZW5lLCBhZXMoeCA9IERQSSwgeSA9IGROZFMsIGNvbG9yID0gZGlldCkpICsKIyAgZ2VvbV9wb2ludCgpICsKIyAgZ2VvbV9saW5lKGFlcyhncm91cCA9IGZlcnJldElEKSkgKwojICBmYWNldF9ncmlkKHNlZ21lbnR+ZGlldCtpbmZfcm91dGUpICsKIyAgUGxvdFRoZW1lMSArCiMgIERpZXRjb2xTY2FsZQojcHJpbnQoZE5kU19mZXJyZXRfZ2VuZV9wbG90KQojZ2dzYXZlKCJkTmRTX2ZlcnJldF9nZW5lX3Bsb3QucGRmIiwgZE5kU19mZXJyZXRfZ2VuZV9wbG90LCBwYXRoID0gc2F2ZWRpcikKI2dnc2F2ZSgiZE5kU19mZXJyZXRfZ2VuZV9wbG90LnBuZyIsIGROZFNfZmVycmV0X2dlbmVfcGxvdCwgcGF0aCA9IHNhdmVkaXIsIGhlaWdodCA9IDEwLCB3aWR0aCA9IDEwKQpgYGAKCkRvIHRoZSBudW1iZXIgb2YgdmFyaWFudHMgY29ycmVsYXRlIHdpdGggbWV0YWJvbGljIG1lYXN1cmVzPwpgYGB7cn0KCmBgYAoKU05WIGxvY2F0aW9uIHBsb3RzCmBgYHtyfQpTTlZMb2NhdGlvbiA9IGdncGxvdChtaW5vcnZkZiwgYWVzKHggPSBudHBvcywgeSA9IGZlcnJldElEKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gZGlldCwgc2hhcGUgPSBjb2hvcnQpKSArCiAgZmFjZXRfZ3JpZChpbmZfcm91dGV+c2VnbWVudCkgKwogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQpwcmludChTTlZMb2NhdGlvbikKZ2dzYXZlKFNOVkxvY2F0aW9uLCBmaWxlID0gIlNOVkxvY2F0aW9uLnBkZiIsIHBhdGggPSBzYXZlZGlyKQojIGZlcnJldCAxNzg3IGRvZXNuJ3QgaGF2ZSBhbnkgdmFyaWFudHM/PwoKbWlub3J2ZGYkdmFyID0gcGFzdGUwKG1pbm9ydmRmJHNlZ21lbnQsIl8iLG1pbm9ydmRmJG1ham9yLG1pbm9ydmRmJG50cG9zLG1pbm9ydmRmJG1pbm9yKQoKIyBDb21wYXJpbmcgdG8gU05WcyBmb3VuZCBpbiB0aGUgc3RvY2sKCnN0b2NrID0gZmlsdGVyKG1pbm9ydmRmLCBEUEkgPT0gIlN0b2NrIikKc3RvY2sgPSBzdG9ja1shZHVwbGljYXRlZChzdG9jayksIF0Kc3RvY2tzbnYgPSBsZXZlbHMoZmFjdG9yKHN0b2NrJHZhcikpCmxlbmd0aChzdG9ja3NudikKCmZlcnJldHMgPSBmaWx0ZXIobWlub3J2ZGYsIERQSSAhPSAiU3RvY2siKQpmZXJyZXRzID0gZmVycmV0c1shZHVwbGljYXRlZChmZXJyZXRzKSwgXQoKc2hhcmVkX3dfc3RvY2sgPSBmZXJyZXRzICU+JSBmaWx0ZXIodmFyICVpbiUgc3RvY2tzbnYpCm5yb3coc2hhcmVkX3dfc3RvY2spCmZlcnVuaXF1ZSA9IGZlcnJldHMgJT4lIGZpbHRlcighKHZhciAlaW4lIHN0b2Nrc252KSkKbnJvdyhmZXJ1bmlxdWUpCmBgYApgYGB7cn0Kc3RvY2tfc2hhcmVkID0gc3RvY2tbIWR1cGxpY2F0ZWQoc3RvY2skdmFyKSxdICU+JSB1bmdyb3VwKCkgCnN0b2NrX3NoYXJlZCA9IHNlcGFyYXRlKHN0b2NrX3NoYXJlZCxzZWdtZW50LCBpbnRvID0gYygic3RyYWluIiwiQ0hST00iKSkKc3RvY2tfc2hhcmVkJG50dmFyID0gcGFzdGUwKHN0b2NrX3NoYXJlZCRtYWpvcixzdG9ja19zaGFyZWQkbnRwb3Msc3RvY2tfc2hhcmVkJG1pbm9yKQpzdG9ja19zaGFyZWQkYWF2YXIgPSBwYXN0ZTAoc3RvY2tfc2hhcmVkJG1ham9yYWEsc3RvY2tfc2hhcmVkJGFhcG9zLHN0b2NrX3NoYXJlZCRtaW5vcmFhKQoKc3RvY2tfc2hhcmVkX3Ntb2wgPSBzZWxlY3Qoc3RvY2tfc2hhcmVkLENIUk9NLG50dmFyLGFhdmFyKSAlPiUgZHJvcGxldmVscygpCmBgYAoKU05WIExvY2F0aW9uIGNvbXBhcmVkIHRvIHN0b2NrCmBgYHtyfQpTdG9ja1NoYXJlZFBsb3QgPSBnZ3Bsb3Qoc2hhcmVkX3dfc3RvY2ssIGFlcyh4ID0gbnRwb3MsIHkgPSBmZXJyZXRJRCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IGRpZXQsIHNoYXBlID0gY29ob3J0KSwgc2l6ZSA9IDIpICsKICBmYWNldF9ncmlkKGluZl9yb3V0ZX5zZWdtZW50LCBkcm9wID0gRkFMU0UpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUgKwogIGdndGl0bGUoIlNOVnMgZm91bmQgaW4gc3RvY2siKQpwcmludChTdG9ja1NoYXJlZFBsb3QpCmdnc2F2ZShTdG9ja1NoYXJlZFBsb3QsIGZpbGUgPSAiU3RvY2tTaGFyZWRQbG90LnBkZiIsIGhlaWdodCA9IDMwLCB3aWR0aCA9IDE1LCBwYXRoID0gc2F2ZWRpcikKCkZlclVuaXF1ZVBsb3QgPSBnZ3Bsb3QoZmVydW5pcXVlLCBhZXMoeCA9IG50cG9zLCB5ID0gZmVycmV0SUQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBkaWV0LCBzaGFwZSA9IGNvaG9ydCkpICsKICBmYWNldF9ncmlkKGluZl9yb3V0ZX5zZWdtZW50KSArCiAgUGxvdFRoZW1lMSArCiAgRGlldGNvbFNjYWxlICsKICBnZ3RpdGxlKCJTTlZzIG5vdCBmb3VuZCBpbiBzdG9jayIpCnByaW50KEZlclVuaXF1ZVBsb3QpCiNnZ3NhdmUoRmVyVW5pcXVlUGxvdCwgZmlsZSA9ICJGZXJVbmlxdWVQbG90LnBkZiIsIHBhdGggPSBzYXZlZGlyKQpgYGAKClN0b2NrIHZhcmlhdGlvbgpgYGB7cn0Kc3RvY2tfcGxvdCA9IGdncGxvdChmaWx0ZXIoc2hhcmVkX3dfc3RvY2ssIGluZl9yb3V0ZSAhPSAiQWVyb3NvbCIpLCAKICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IERQSSwgeSA9IG1pbm9yZnJlcSwgY29sb3IgPSBmZXJyZXRJRCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBmZXJyZXRJRCkpICsKICBmYWNldF9ncmlkKHZhcn5kaWV0K2luZl9yb3V0ZSkgKwogIFBsb3RUaGVtZTEKZ2dzYXZlKCJzdG9ja19wbG90LnBkZiIsIHN0b2NrX3Bsb3QsIHdpZHRoID0gOCwgaGVpZ2h0ID0gMjAsIHBhdGggPSBzYXZlZGlyKQpgYGAKCkRlIG5vdm8gU05WcwpgYGB7cn0KZGVub3ZvID0gdW5ncm91cChmZXJyZXRzKSAlPiUgY291bnQodmFyKQoKZmlsdGVyKGZlcnJldHMsIHZhciA9PSAiSDlOMl9QQjJfQTIyMTRDIikgJT4lIHVuZ3JvdXAoKSAlPiUgY291bnQoZmVycmV0SUQsRFBJKQpmaWx0ZXIoZmVycmV0cywgdmFyID09ICJIOU4yX1BCMl9BMjIxNEMiKSAlPiUgY291bnQobWlub3JmcmVxKQojIGZvdW5kIGluIGJhc2ljYWxseSBldmVyeSBzYW1wbGUgd2l0aCBhIGZyZXEgb2YgMi01JSB3aGF0IGlzIHRoaXMKYGBgClZlbm4gZGlhZ3JhbSBvZiBvYmVzZSBhbmQgbGVhbiBkZSBub3ZvIFNOVnMKYGBge3J9Cm9fdmFyID0gZmlsdGVyKGZlcnJldHMsIGRpZXQgPT0gIk9iZXNlIikgCm9fdmFyID0gdW5pcXVlKG9fdmFyJHZhcikKCmxfdmFyID0gZmlsdGVyKGZlcnJldHMsIGRpZXQgPT0gIkxlYW4iKSAKbF92YXIgPSB1bmlxdWUobF92YXIkdmFyKQoKZGlldF92YXIgPC0gbGlzdChPYmVzZSA9IG9fdmFyLCBMZWFuID0gbF92YXIpCgojRGlldFVuaXF1ZVNOVlMgPSBnZ1Zlbm5EaWFncmFtKGRpZXRfdmFyKQojcHJpbnQoRGlldFVuaXF1ZVNOVlMpCiNnZ3NhdmUoRGlldFVuaXF1ZVNOVlMsIGZpbGUgPSAiRGlldFVuaXF1ZVNOVlMucGRmIiwgcGF0aCA9IHNhdmVkaXIpCmBgYAoKT2Jlc2UtIGFuZCBsZWFuLXNwZWNpZmljIFNOVnMKYGBge3J9CmxlYW4gPSBmZXJyZXRzICU+JSAKICBmaWx0ZXIodmFyICVpbiUgbF92YXIpICU+JSAKICBmaWx0ZXIoISh2YXIgJWluJSBvX3ZhcikpIAoKbGVhbiRzYW1wbGVfdmFyID0gcGFzdGUwKGxlYW4kc2FtcGxlLCJfIixsZWFuJHZhcikKbGVhbiA9IGxlYW5bIWR1cGxpY2F0ZWQobGVhbiRzYW1wbGVfdmFyKSxdIAoKbGVhbiRmZXJyZXRJRF92YXIgPSBwYXN0ZTAobGVhbiRmZXJyZXRJRCwiXyIsbGVhbiR2YXIpCmxlYW4gPSBsZWFuWyFkdXBsaWNhdGVkKGxlYW4kZmVycmV0SURfdmFyKSxdIAoKbGVhbiA9IGxlYW4gJT4lIAogIGdyb3VwX2J5KHZhcikgJT4lIAogIG11dGF0ZShjb3VudCA9IDEsIHRvdGFsc2FtcCA9IHN1bShjb3VudCkpCgpvYmVzZSA9IGZlcnJldHMgJT4lIAogIGZpbHRlcih2YXIgJWluJSBvX3ZhcikgJT4lIAogIGZpbHRlcighKHZhciAlaW4lIGxfdmFyKSkgCgpvYmVzZSRzYW1wbGVfdmFyID0gcGFzdGUwKG9iZXNlJHNhbXBsZSwiXyIsb2Jlc2UkdmFyKQpvYmVzZSA9IG9iZXNlWyFkdXBsaWNhdGVkKG9iZXNlJHNhbXBsZV92YXIpLF0gCgpvYmVzZSRmZXJyZXRJRF92YXIgPSBwYXN0ZTAob2Jlc2UkZmVycmV0SUQsIl8iLG9iZXNlJHZhcikKb2Jlc2UgPSBvYmVzZVshZHVwbGljYXRlZChvYmVzZSRmZXJyZXRJRF92YXIpLF0gCgpvYmVzZSA9IG9iZXNlICU+JSAKICBncm91cF9ieSh2YXIpICU+JSAKICBtdXRhdGUoY291bnQgPSAxLCB0b3RhbHNhbXAgPSBzdW0oY291bnQpKQoKZGlldHVuaXF1ZSA9IHJiaW5kKGxlYW4sb2Jlc2UpCmRpZXR1bmlxdWUgPSBkaWV0dW5pcXVlWyFkdXBsaWNhdGVkKGRpZXR1bmlxdWUpLCBdICU+JSBkcm9wbGV2ZWxzKCkKZGlldHVuaXF1ZSA9IGZpbHRlcihkaWV0dW5pcXVlLCBpbmZfcm91dGUgIT0gIkFlcm9zb2wiKQogIApEaWV0VW5pcXVlID0gZ2dwbG90KGRpZXR1bmlxdWUsIGFlcyh4ID0gbnRwb3MsIHkgPSBzZWdtZW50KSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gbm9uc3luLCBzaXplID0gdG90YWxzYW1wKSkgKyAKICBnZ3RpdGxlKCJOdW1iZXIgb2Ygc2FtcGxlcyBjb250YWluaW5nIGVhY2ggdmFyaWFudCAtIGRpZXQgc3BlY2lmaWMiKSArCiAgdGhlbWUobGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXI9ImJsYWNrIiwgZmlsbD0id2hpdGUiKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpKSArCiAgZmFjZXRfZ3JpZChkaWV0flNUUkFJTikgKwogIFBsb3RUaGVtZTEKcHJpbnQoRGlldFVuaXF1ZSkKZ2dzYXZlKERpZXRVbmlxdWUsIGZpbGVuYW1lID0gIlNlZ21lbnRTTlZQbG90X0RpZXRVbnFpcXVlLnBkZiIsIHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQpgYGAKCmBgYHtyfQojIG1ha2UgbmV3IHZlcnNpb24gb2YgdGhpcyBmaWd1cmUsIHNlcGFyYXRpbmcgb3V0IHRyYW5zbWlzc2lvbiB2IGluZGVwZW5kZW50IGZlcnJldHMKRGlldFVuaXF1ZV9JbmZSb3V0ZSA9IGdncGxvdChkaWV0dW5pcXVlLCBhZXMoeCA9IG50cG9zLCB5ID0gc2VnbWVudCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IG5vbnN5biwgc2l6ZSA9IHRvdGFsc2FtcCkpICsgCiAgZ2d0aXRsZSgiTnVtYmVyIG9mIHNhbXBsZXMgY29udGFpbmluZyBlYWNoIHZhcmlhbnQgLSBkaWV0IHNwZWNpZmljIikgKwogIHRoZW1lKGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyPSJibGFjayIsIGZpbGw9IndoaXRlIiksCiAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSkgKwogIGZhY2V0X2dyaWQoZGlldH5pbmZfcm91dGUpICsKICBQbG90VGhlbWUxCnByaW50KERpZXRVbmlxdWVfSW5mUm91dGUpCmdnc2F2ZShEaWV0VW5pcXVlX0luZlJvdXRlLCBmaWxlbmFtZSA9ICJTZWdtZW50U05WUGxvdF9EaWV0VW5xaXF1ZV9JbmZSb3V0ZS5wZGYiLCAKICAgICAgIHBhdGggPSBzYXZlZGlyLCB3aWR0aCA9IDE1LCBoZWlnaHQgPSAxMCkKZ2dzYXZlKERpZXRVbmlxdWVfSW5mUm91dGUsIGZpbGVuYW1lID0gIlNlZ21lbnRTTlZQbG90X0RpZXRVbnFpcXVlX0luZlJvdXRlLnBuZyIsIAogICAgICAgcGF0aCA9IHNhdmVkaXIsIHdpZHRoID0gMTUsIGhlaWdodCA9IDEwKQpgYGAKCmROZFMgYW5hbHlzaXMgb2YgZGUgbm92bywgZGlldCB1bmlxdWUgZ2VuZXMKYGBge3J9CiMgYnkgZmVycmV0CmROZFNfZGVub3ZvX2ZlcnJldCA9IGRpZXR1bmlxdWUgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZmVycmV0SUQsRFBJLGRpZXQsaW5mX3JvdXRlKSAlPiUgCiAgY291bnQobm9uc3luKQoKZE5kU19kZW5vdm9fZmVycmV0ID0gcGl2b3Rfd2lkZXIoZE5kU19kZW5vdm9fZmVycmV0LG5hbWVzX2Zyb20gPSBub25zeW4sIHZhbHVlc19mcm9tID0gbikKZE5kU19kZW5vdm9fZmVycmV0ID0gc2VsZWN0KGROZFNfZGVub3ZvX2ZlcnJldCwgZmVycmV0SUQsRFBJLG5vbnN5bixzeW4pCmROZFNfZGVub3ZvX2ZlcnJldCRkTmRTID0gcGFzdGUwKGROZFNfZGVub3ZvX2ZlcnJldCRub25zeW4gLyBkTmRTX2Rlbm92b19mZXJyZXQkc3luKQpkTmRTX2Rlbm92b19mZXJyZXQkZE5kUyA9IGFzLm51bWVyaWMoZE5kU19kZW5vdm9fZmVycmV0JGROZFMpCgpkTmRTX2Rlbm92b19mZXJyZXRfcGxvdCA9IGdncGxvdChkTmRTX2Rlbm92b19mZXJyZXQsIGFlcyh4ID0gRFBJLCB5ID0gZE5kUywgY29sb3IgPSBmZXJyZXRJRCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBmZXJyZXRJRCkpICsKICBmYWNldF9ncmlkKH5kaWV0K2luZl9yb3V0ZSkgKwogIFBsb3RUaGVtZTEgCnByaW50KGROZFNfZGVub3ZvX2ZlcnJldF9wbG90KQpnZ3NhdmUoImROZFNfZGVub3ZvX2ZlcnJldC5wZGYiLCBkTmRTX2Rlbm92b19mZXJyZXRfcGxvdCwgcGF0aCA9IHNhdmVkaXIpCmdnc2F2ZSgiZE5kU19kZW5vdm9fZmVycmV0LnBuZyIsIGROZFNfZGVub3ZvX2ZlcnJldF9wbG90LCBwYXRoID0gc2F2ZWRpciwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSkKYGBgCgpgYGB7cn0KIyBieSBmZXJyZXQgYW5kIGdlbmUKZE5kU19kZW5vdm9fZmVycmV0X2dlbmUgPSBkaWV0dW5pcXVlICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGdyb3VwX2J5KGZlcnJldElELERQSSxkaWV0LGluZl9yb3V0ZSxzZWdtZW50KSAlPiUgCiAgY291bnQobm9uc3luKQoKZE5kU19kZW5vdm9fZmVycmV0X2dlbmUgPSBwaXZvdF93aWRlcihkTmRTX2Rlbm92b19mZXJyZXRfZ2VuZSxuYW1lc19mcm9tID0gbm9uc3luLCB2YWx1ZXNfZnJvbSA9IG4pCmROZFNfZGVub3ZvX2ZlcnJldF9nZW5lID0gc2VsZWN0KGROZFNfZGVub3ZvX2ZlcnJldF9nZW5lLCBmZXJyZXRJRCxEUEksbm9uc3luLHN5bikKZE5kU19kZW5vdm9fZmVycmV0X2dlbmUkZE5kUyA9IHBhc3RlMChkTmRTX2Rlbm92b19mZXJyZXRfZ2VuZSRub25zeW4gLyBkTmRTX2Rlbm92b19mZXJyZXRfZ2VuZSRzeW4pCmROZFNfZGVub3ZvX2ZlcnJldF9nZW5lJGROZFMgPSBhcy5udW1lcmljKGROZFNfZGVub3ZvX2ZlcnJldF9nZW5lJGROZFMpCgpkTmRTX2Rlbm92b19mZXJyZXRfZ2VuZV9wbG90ID0gZ2dwbG90KGROZFNfZGVub3ZvX2ZlcnJldF9nZW5lLCBhZXMoeCA9IERQSSwgeSA9IGROZFMsIGNvbG9yID0gZGlldCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBmZXJyZXRJRCkpICsKICBmYWNldF9ncmlkKHNlZ21lbnR+ZGlldCtpbmZfcm91dGUpICsKICBQbG90VGhlbWUxICsKICBEaWV0Y29sU2NhbGUKcHJpbnQoZE5kU19kZW5vdm9fZmVycmV0X2dlbmVfcGxvdCkKZ2dzYXZlKCJkTmRTX2Rlbm92b19mZXJyZXRfZ2VuZV9wbG90LnBkZiIsIGROZFNfZGVub3ZvX2ZlcnJldF9nZW5lX3Bsb3QsIHBhdGggPSBzYXZlZGlyKQpnZ3NhdmUoImROZFNfZGVub3ZvX2ZlcnJldF9nZW5lX3Bsb3QucG5nIiwgZE5kU19kZW5vdm9fZmVycmV0X2dlbmVfcGxvdCwgcGF0aCA9IHNhdmVkaXIpCmBgYAoKYGBge3J9CiNnZ3Bsb3QoZmlsdGVyKGRpZXR1bmlxdWUsIHRvdGFsc2FtcCA+IDEpLCBhZXMoeCA9IERQSSwgeSA9IG1pbm9yZnJlcSwgY29sb3IgPSBub25zeW4pKSArCiMgIGdlb21fcG9pbnQoKSArCiMgIGdlb21fbGluZShhZXMoZ3JvdXAgPSB2YXIpKSArCiMgIGZhY2V0X2dyaWQoZmVycmV0SUR+ZGlldCtpbmZfcm91dGUpICsKIyAgUGxvdFRoZW1lMSAKYGBgCgpgYGB7cn0Kbm9uc3lucyA9IGZpbHRlcihkaWV0dW5pcXVlLCBub25zeW4gPT0gIm5vbnN5biIgJiB0b3RhbHNhbXAgPiAxKSAlPiUgdW5ncm91cCgpICU+JSBkcm9wbGV2ZWxzKCkKbm9uc3lucyA9IG5vbnN5bnNbIWR1cGxpY2F0ZWQobm9uc3lucyR2YXIpLF0gCgpub25zeW5zID0gc2VwYXJhdGUobm9uc3lucyxzZWdtZW50LCBpbnRvID0gYygic3RyYWluIiwiQ0hST00iKSkKbm9uc3lucyRudHZhciA9IHBhc3RlMChub25zeW5zJG1ham9yLG5vbnN5bnMkbnRwb3Msbm9uc3lucyRtaW5vcikKbm9uc3lucyRhYXZhciA9IHBhc3RlMChub25zeW5zJG1ham9yYWEsbm9uc3lucyRhYXBvcyxub25zeW5zJG1pbm9yYWEpCgpub25zeW5zX3Ntb2wgPSBzZWxlY3Qobm9uc3lucyxDSFJPTSxudHZhcixhYXZhcixkaWV0LHRvdGFsc2FtcCkgJT4lIGRyb3BsZXZlbHMoKQp3cml0ZS5jc3Yobm9uc3luc19zbW9sLCAibm9uc3lucy5jc3YiKQpgYGAKCldoaWNoIGZlcnJldHMgaGF2ZSBtb3JlIHRoYW4gb25lIGRlIG5vdm8/CmBgYHtyfQpnZ3Bsb3QoZGlldHVuaXF1ZSwgYWVzKHggPSBudHBvcywgeSA9IGZlcnJldElEKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gZGlldCkpICsKICBmYWNldF9ncmlkKH5zZWdtZW50KSArCiAgUGxvdFRoZW1lMSArCiAgRGlldGNvbFNjYWxlCgpnZ3Bsb3QoZmlsdGVyKGRpZXR1bmlxdWUsIHRvdGFsc2FtcCA+MSksIGFlcyh4ID0gbnRwb3MsIHkgPSBmZXJyZXRJRCkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IGRpZXQpKSArCiAgZmFjZXRfZ3JpZCh+c2VnbWVudCkgKwogIFBsb3RUaGVtZTEgKwogIERpZXRjb2xTY2FsZQpgYGAKCkFGIG9mIHNoYXJlZCBkZSBub3ZvcwpgYGB7cn0KZ2dwbG90KGZpbHRlcihkaWV0dW5pcXVlLCB0b3RhbHNhbXAgPjEpLCBhZXMoeCA9IERQSSwgeSA9IG1pbm9yZnJlcSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHZhcikpICsKICBmYWNldF9ncmlkKH5mZXJyZXRJRCkgKwogIFBsb3RUaGVtZTEKYGBgCgpTTlZzIHNoYXJlZCBiZXR3ZWVuIGRpZXQgZ3JvdXBzCmBgYHtyfQpzaGFyZWQgPSBmZXJyZXRzICU+JSAKICBmaWx0ZXIodmFyICVpbiUgb192YXIpICU+JSAKICBmaWx0ZXIodmFyICVpbiUgbF92YXIpICU+JSAKICBncm91cF9ieSh2YXIpICU+JSAKICBtdXRhdGUoY291bnQgPSAxLCB0b3RhbHNhbXAgPSBzdW0oY291bnQpKQoKU2hhcmVkUGxvdCA9IGdncGxvdChzaGFyZWQsIGFlcyh4ID0gbnRwb3MsIHkgPSBzZWdtZW50KSkgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSB0b3RhbHNhbXAsIGNvbG9yID0gbm9uc3luKSkgKwogIGdndGl0bGUoIk51bWJlciBvZiBzYW1wbGVzIGNvbnRhaW5pbmcgZWFjaCB2YXJpYW50IC0gU2hhcmVkIGJldHdlZW4gZGlldCBncm91cHMiKSArCiAgdGhlbWUobGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXI9ImJsYWNrIiwgZmlsbD0id2hpdGUiKSwKICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpKSArCiAgUGxvdFRoZW1lMQpwcmludChTaGFyZWRQbG90KQpnZ3NhdmUoU2hhcmVkUGxvdCwgZmlsZW5hbWUgPSAiU2VnbWVudFNOVlBsb3RfRGlldFNoYXJlZC5wZGYiLCBwYXRoID0gc2F2ZWRpcikKYGBgCgpgYGB7cn0KTWlub3JmcmVxX2Rpc3QgPSBnZ3Bsb3QoZmVycmV0cywgYWVzKHggPSBtaW5vcmZyZXEsIGZpbGwgPSBkaWV0KSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4wMSkgKwogIFBsb3RUaGVtZTEgKwogIGZhY2V0X2dyaWQoaW5mX3JvdXRlfmRpZXQpICsKICBEaWV0Y29sU2NhbGVfZmlsbApwcmludChNaW5vcmZyZXFfZGlzdCkKZ2dzYXZlKCJNaW5vcmZyZXFfZGlzdC5wZGYiLCBNaW5vcmZyZXFfZGlzdCwgcGF0aCA9IHNhdmVkaXIpCiMgb2Jlc2Ugc2VlbSB0byBoYXZlIGZld2VyIGxvdy1mcmVxdWVuY3kgZGUgbm92byBTTlZzCmBgYAoKYGBge3J9Cm9iZXNlX2luZGV4ID0gZmlsdGVyKGZlcnJldHMsIGRpZXQgPT0gIk9iZXNlIiAmIGluZl9yb3V0ZSA9PSAiSW5kZXgiKSAlPiUgdW5ncm91cCgpCmxlYW5faW5kZXggPSBmaWx0ZXIoZmVycmV0cywgZGlldCA9PSAiTGVhbiIgJiBpbmZfcm91dGUgPT0gIkluZGV4IikgJT4lIHVuZ3JvdXAoKQp0LnRlc3Qob2Jlc2VfaW5kZXgkbWlub3JmcmVxLCBsZWFuX2luZGV4JG1pbm9yZnJlcSkKIyBtZWFucyBhcmUgbm90IGRpZmZlcmVudAoKb2Jlc2VfY29udGFjdCA9IGZpbHRlcihmZXJyZXRzLCBkaWV0ID09ICJPYmVzZSIgJiBpbmZfcm91dGUgPT0gIkNvbnRhY3QiKSAlPiUgdW5ncm91cCgpCmxlYW5fY29udGFjdCA9IGZpbHRlcihmZXJyZXRzLCBkaWV0ID09ICJMZWFuIiAmIGluZl9yb3V0ZSA9PSAiQ29udGFjdCIpICU+JSB1bmdyb3VwKCkKdC50ZXN0KG9iZXNlX2NvbnRhY3QkbWlub3JmcmVxLCBsZWFuX2NvbnRhY3QkbWlub3JmcmVxKQojIG1lYW5zIGFyZSBub3QgZGlmZmVyZW50CgojIFFRX1Bsb3Q6IGNvbXBhcmVzIHRoZSBxdWFudGlsZXMgb2YgdHdvIGRpc3RyaWJ1dGlvbnMsIHggPXkgc3VnZ2VzdHMgdGhleSBhcmUgZHJhd24gZnJvbSB0aGUgc2FtZSBkaXN0cmlidXRpb24KcXFub3JtKG9iZXNlX2luZGV4JG1pbm9yZnJlcSwgbWFpbiA9ICJPYmVzZSBJbmRleCAtIFRlc3Qgb2YgTm9ybWFsIERpc3RyaWJ1dGlvbiIpCnFxbm9ybShsZWFuX2luZGV4JG1pbm9yZnJlcSwgbWFpbiA9ICJMZWFuIEluZGV4IC0gVGVzdCBvZiBOb3JtYWwgRGlzdHJpYnV0aW9uIikKIyBuZWl0aGVyIGRpc3RyaWJ1dGlvbiBpcyBub3JtYWwKcXFwbG90KG9iZXNlX2luZGV4JG1pbm9yZnJlcSxsZWFuX2luZGV4JG1pbm9yZnJlcSwgeGxhYiA9ICJPYmVzZSBJbmRleCIsIHlsYWIgPSAiTGVhbiBJbmRleCIpCgpxcW5vcm0ob2Jlc2VfY29udGFjdCRtaW5vcmZyZXEsIG1haW4gPSAiT2Jlc2UgQ29udGFjdCAtIFRlc3Qgb2YgTm9ybWFsIERpc3RyaWJ1dGlvbiIpCnFxbm9ybShsZWFuX2NvbnRhY3QkbWlub3JmcmVxLCBtYWluID0gIkxlYW4gQ29udGFjdCAtIFRlc3Qgb2YgTm9ybWFsIERpc3RyaWJ1dGlvbiIpCiMgbmVpdGhlciBkaXN0cmlidXRpb24gaXMgbm9ybWFsCnFxcGxvdChvYmVzZV9jb250YWN0JG1pbm9yZnJlcSxsZWFuX2NvbnRhY3QkbWlub3JmcmVxLCB4bGFiID0gIk9iZXNlIENvbnRhY3QiLCB5bGFiID0gIkxlYW4gQ29udGFjdCIpCgojIE1hbm4tV2hpdG5leS1XaWxjb3ggdGVzdCAoTWFubi1XaGl0bmV5IFUgdGVzdCk6IHNhbXBsZXMgYXJlIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgaW5kZXBlbmRlbnQgb2YgZWFjaCBvdGhlcgp3aWxjb3gudGVzdChvYmVzZV9pbmRleCRtaW5vcmZyZXEsbGVhbl9pbmRleCRtaW5vcmZyZXEpCndpbGNveC50ZXN0KG9iZXNlX2NvbnRhY3QkbWlub3JmcmVxLGxlYW5fY29udGFjdCRtaW5vcmZyZXEpCiMgZGlzdHJpYnV0aW9ucyBhcmUgbm90IGRpZmZlcmVudAoKIyBLb2xtb2dvcm92LVNtaXJub3YgdGVzdDogc2FtcGxlcyBhcmUgbm90IG5vcm1hbGx5IGRpc3RyaWJ1dGVkIGFuZCBpbmRlcGVuZGVudCBvZiBlYWNoIG90aGVyCiMgInNlbnNpdGl2ZSB0byBkaWZmZXJlbmNlcyBpbiBsb2NhdGlvbiBhbmQgc2hhcGUgb2YgdGhlIGVtcGlyaWNhbCBDREZzIG9mIHRoZSB0d28gc2FtcGxlcyIKa3MudGVzdChvYmVzZV9pbmRleCRtaW5vcmZyZXEsbGVhbl9pbmRleCRtaW5vcmZyZXEpCmtzLnRlc3Qob2Jlc2VfY29udGFjdCRtaW5vcmZyZXEsbGVhbl9jb250YWN0JG1pbm9yZnJlcSkKIyBkaXN0cmlidXRpb25zIGFyZSBub3QgZGlmZmVyZW50CmBgYAoKYGBge3J9CmhpZ2hmcmVxID0gZmlsdGVyKGZlcnJldHMsIG1pbm9yZnJlcSA+IDAuMjUpCmBgYAo=